iDempiere Architecture Overview

Level: Beginner Module: General Foundation 17 min read Lesson 2 of 47

Overview

  • What you’ll learn:
    • The three-tier architecture of iDempiere: database tier, application server tier, and web client tier
    • How OSGi and the Eclipse Equinox container enable modular plugin-based development
    • The role of the Application Dictionary in model-driven development and how a request flows from browser to database and back
  • Prerequisites: Lesson 1 — What is iDempiere?
  • Estimated reading time: 18 minutes

Introduction

Understanding iDempiere’s architecture is essential whether you plan to implement the system for a business, develop plugins to extend its functionality, or simply administer an existing installation. The architectural decisions made by the iDempiere founders — adopting OSGi modularity, the ZK web framework, and preserving the Application Dictionary from its Compiere heritage — define how the system behaves, how it is extended, and how it scales.

In this lesson, we will dissect iDempiere’s architecture layer by layer. By the end, you will have a clear mental model of how all the pieces fit together — from the moment a user clicks a button in their browser to the instant the results appear on screen.

The Three-Tier Architecture

iDempiere follows a classic three-tier architecture pattern, where responsibilities are separated into distinct layers. This separation promotes maintainability, scalability, and the ability to modify one tier without disrupting the others.

Tier 1: The Database

At the foundation of iDempiere sits the relational database, which serves as the persistent data store for all business data, configuration, and metadata. iDempiere supports two database systems:

  • PostgreSQL (version 14 or higher) — the primary and most widely used option in the community. PostgreSQL is free, open-source, and provides excellent performance, reliability, and standards compliance.
  • Oracle Database (version 12c or higher) — supported for organizations that have existing Oracle infrastructure or licensing. Oracle support has been part of the system since the original Compiere days.

The database stores far more than just transactional data (orders, invoices, payments). It also stores the Application Dictionary — the metadata that defines the application itself. Tables like AD_Window, AD_Tab, AD_Field, AD_Column, and AD_Table describe the structure of every window, tab, and field in the user interface. This means the database is both the data store and the application definition repository.

Key database concepts in iDempiere include:

  • AD_Client_ID and AD_Org_ID: Nearly every table includes these columns, enabling multi-tenant data isolation and organizational segmentation at the database level.
  • IsActive flag: Records are soft-deleted by setting IsActive = 'N' rather than being physically removed, preserving audit trails and referential integrity.
  • Created/Updated timestamps and CreatedBy/UpdatedBy: Every record tracks when it was created and last modified, and by which user, providing a built-in audit trail.

Tier 2: The Application Server

The middle tier is the iDempiere application server, a Java-based process that runs inside the Eclipse Equinox OSGi container. This is where business logic executes: processing documents, running workflows, performing calculations, enforcing validation rules, and coordinating between the database and the user interface.

The application server handles:

  • Business logic execution: Model classes (Java POJOs that correspond to database tables) contain the logic for validating, processing, and completing business documents.
  • Process scheduling: Background processes and scheduled tasks (such as nightly accounting runs or automated report generation) are managed by the server’s scheduler.
  • Session management: User authentication, session tracking, and security context (which client, organization, role, and warehouse the user is operating in) are maintained at this tier.
  • Caching: The application server caches Application Dictionary metadata, reference data, and frequently accessed configuration to minimize database queries and improve response times.

Tier 3: The Web Client

The presentation tier is a web-based user interface built on the ZK Framework, an Ajax-based web application framework for Java. Users access iDempiere through a standard web browser — no client-side software installation is required.

The ZK Framework uses a server-centric programming model: UI components are created and managed on the server side in Java, and ZK automatically synchronizes the state between the server and the browser using Ajax calls. This means that iDempiere developers write Java code to define UI behavior, and ZK handles all the HTML, CSS, and JavaScript generation and communication.

Key characteristics of the web client:

  • No plugins or applets required: The interface runs in any modern web browser (Chrome, Firefox, Edge, Safari).
  • Desktop-like experience: ZK provides rich UI components — trees, grids, tabs, dialogs, drag-and-drop — that feel more like a desktop application than a traditional web page.
  • Responsive communication: ZK uses Ajax to send only incremental UI updates rather than reloading entire pages, resulting in a smooth, responsive user experience.

OSGi and the Eclipse Equinox Container

The adoption of OSGi is what fundamentally distinguishes iDempiere from its predecessors (Compiere and ADempiere). Understanding OSGi is crucial for anyone who wants to extend or customize iDempiere.

What is OSGi?

OSGi (Open Services Gateway initiative) is a modularity framework for Java. It defines a system of bundles (modules) that can be independently developed, deployed, started, stopped, updated, and uninstalled — all without restarting the application. Each bundle has explicit declarations of what packages it exports (makes available to other bundles) and what packages it imports (requires from other bundles).

Think of OSGi bundles like apps on a smartphone: each one is self-contained, declares what it needs, and can be installed or removed without affecting the phone’s operating system or other apps.

How iDempiere Uses OSGi

iDempiere runs inside the Eclipse Equinox OSGi container, which is the same OSGi runtime that powers the Eclipse IDE. The iDempiere core is itself composed of multiple OSGi bundles:

  • org.adempiere.base — Core business logic, model classes, and utility functions
  • org.adempiere.ui.zk — The ZK-based web user interface
  • org.adempiere.server — Server processes, schedulers, and background tasks
  • org.adempiere.report.jasper — JasperReports integration for formatted reporting
  • org.adempiere.install — Installation and setup utilities

When developers create plugins for iDempiere, they create new OSGi bundles that declare dependencies on the core bundles and register extensions through well-defined extension points. The most important extension mechanisms include:

  • Model Validators: Plugins can register listeners that fire before or after records are saved, deleted, or documents are processed. This is the primary mechanism for adding custom business logic.
  • Callouts: Plugins can register field-level event handlers that execute when a user changes a value in a form field, enabling real-time field calculations and auto-population.
  • Process classes: Plugins can add new executable processes that appear in the iDempiere menu or can be attached to toolbar buttons.
  • Form classes: Plugins can define custom user interface forms for specialized data entry or display needs.
  • Event Handlers: Using OSGi’s event admin service, plugins can subscribe to and react to system events asynchronously.

Why OSGi Matters

The OSGi architecture provides several critical benefits:

  1. Clean separation: Custom code lives in separate plugin bundles, never mixed into the core source code. This makes upgrades dramatically easier — you update the core and your plugins continue to work (assuming the APIs they depend on haven’t changed).
  2. Runtime deployment: Plugins can be installed and updated while iDempiere is running. In many cases, you do not need to restart the server to activate a new plugin.
  3. Dependency management: OSGi enforces explicit dependency declarations, preventing classpath conflicts and ensuring that bundles load in the correct order.
  4. Isolation: Each bundle has its own classloader, preventing unintended interactions between plugins and reducing the risk that one plugin’s code breaks another.

The Plugin Bundle Structure

A typical iDempiere plugin bundle is structured as follows:

com.example.myplugin/
├── META-INF/
│   └── MANIFEST.MF          # OSGi bundle metadata (name, version, dependencies)
├── src/
│   └── com/example/myplugin/
│       ├── Activator.java    # Bundle lifecycle management
│       ├── MyModelValidator.java
│       └── MyProcess.java
├── OSGI-INF/
│   └── component.xml         # OSGi Declarative Services component definitions
├── plugin.xml                # Eclipse extension point registrations
└── build.properties          # Build configuration

The MANIFEST.MF file is the most important descriptor. It declares the bundle’s symbolic name, version, the packages it imports, and the packages it exports:

Bundle-SymbolicName: com.example.myplugin
Bundle-Version: 1.0.0
Require-Bundle: org.adempiere.base;bundle-version="12.0.0"
Import-Package: org.compiere.model,
 org.compiere.process,
 org.compiere.util

The Application Dictionary: Model-Driven Development

The Application Dictionary (AD) is the heart of iDempiere’s configurability. It is a set of metadata tables in the database that describe every aspect of the application’s structure and behavior.

How the Dictionary Works

When a user opens a window in iDempiere, the system does not load a hard-coded Java screen. Instead, it queries the Application Dictionary to determine:

  1. What tabs the window contains (from AD_Tab)
  2. What fields each tab displays (from AD_Field, linked to AD_Column)
  3. What table each tab is bound to (from AD_Table)
  4. What validation rules apply to each field (from AD_Val_Rule)
  5. What callouts fire when field values change (from AD_Column.Callout)
  6. What display logic controls field visibility (from AD_Field.DisplayLogic)
  7. What default values to populate for new records (from AD_Column.DefaultValue)

The ZK UI layer reads this metadata and dynamically generates the appropriate user interface components. This is why you can add a new column to a table, define it in the Application Dictionary, and immediately see it in the user interface — without writing any Java or JavaScript code.

Key Dictionary Tables

Table Purpose
AD_Table Defines database tables registered in the system
AD_Column Defines columns within tables, including data type, default value, validation, and callout references
AD_Window Defines application windows (the top-level UI container)
AD_Tab Defines tabs within a window, each bound to a table
AD_Field Defines individual fields within a tab, controlling display sequence, read-only logic, and display logic
AD_Process Defines executable processes (reports, batch jobs, actions)
AD_Menu Defines the navigation menu tree
AD_Reference Defines dropdown lists, search lookups, and other reference types
AD_Val_Rule Defines SQL-based validation rules that filter dropdown values dynamically
AD_Workflow Defines document approval workflows and automated processes

The Power of Model-Driven Development

The Application Dictionary approach means that a significant portion of iDempiere customization can be performed by functional consultants through the application’s own user interface, without writing code. Common dictionary-level customizations include:

  • Adding new fields to existing windows
  • Creating entirely new windows, tabs, and fields for custom tables
  • Defining validation rules that control what values appear in dropdown lists
  • Setting up display logic to show or hide fields based on other field values
  • Configuring default values using context variables and SQL expressions
  • Building document workflows with approval steps and automated actions

Key Layers: Persistence, Model, and UI

Within the application server, iDempiere’s code is organized into three conceptual layers:

Persistence Layer

The persistence layer handles all communication with the database. iDempiere uses its own persistence framework (rather than an external ORM like Hibernate) built around the PO (Persistent Object) base class. Every business entity — orders, invoices, products, business partners — is represented by a Java class that extends PO. These model classes are largely auto-generated from the Application Dictionary, with methods like getC_Order_ID(), setDateOrdered(), and getDocStatus() corresponding directly to database columns.

The PO class provides:

  • Automatic SQL generation for SELECT, INSERT, UPDATE, and DELETE operations
  • Transparent handling of multi-tenant filtering (AD_Client_ID)
  • Before-save and after-save event hooks for business logic
  • Change logging for audit trail
  • Caching of frequently accessed records

Model / Business Logic Layer

The model layer contains the business logic that operates on persistent objects. For documents (orders, invoices, payments, shipments), this includes the document processing engine that manages the document lifecycle: Draft → In Progress → Completed → Closed (or Voided/Reversed). The model layer enforces business rules — for example, ensuring that an invoice cannot be completed if there is no valid tax configuration, or that inventory cannot go negative if the warehouse is configured to disallow it.

Key classes in the model layer include:

  • MOrder, MInvoice, MPayment, MInOut — Document model classes with processing logic
  • DocAction — The interface that defines the document processing lifecycle
  • Doc and its subclasses — The accounting engine that generates GL journal entries from business documents
  • MProcess — The process execution framework

UI Layer

The UI layer is built on the ZK Framework and is responsible for rendering the user interface in the browser. Key components include:

  • ADWindow: The generic window renderer that reads Application Dictionary metadata and dynamically constructs the UI
  • ADForm: The base class for custom forms that need specialized UI beyond what the dictionary can describe
  • GridTable / GridField: The data-binding layer that connects UI components to the underlying model objects
  • WEditor: Editor components for different field types (text, number, date, lookup, etc.)

How a Request Flows Through iDempiere

To tie everything together, let us trace what happens when a user opens a Sales Order window and saves a new order:

  1. Browser → ZK Engine: The user clicks “Sales Order” in the menu. The browser sends an Ajax request to the server-side ZK engine.
  2. ZK Engine → Application Dictionary: The ZK ADWindow component queries the Application Dictionary tables (AD_Window, AD_Tab, AD_Field) to determine the window structure.
  3. Dictionary → UI Rendering: Based on the dictionary metadata, ZK dynamically creates the appropriate UI components (tabs, fields, buttons, grids) and sends the rendered HTML/JavaScript back to the browser.
  4. User Enters Data: As the user fills in fields, callouts fire on the server side (via Ajax) to perform real-time calculations — for example, selecting a Business Partner automatically populates the payment terms, price list, and shipping address.
  5. Save Request: When the user clicks Save, an Ajax request sends the field values to the server.
  6. Model Validation: The MOrder model class validates the data — checking required fields, verifying referential integrity, running any registered Model Validators from plugins.
  7. Persistence: The PO.saveEx() method generates the appropriate SQL INSERT or UPDATE statement and executes it against the database within a transaction.
  8. Response: On success, the server updates the UI state and ZK sends an Ajax response to the browser confirming the save, updating status indicators, and refreshing any calculated fields.

This entire round trip typically completes in milliseconds for simple operations, demonstrating the efficiency of the server-centric ZK model combined with iDempiere’s caching layer.

Key Takeaways

  • iDempiere uses a three-tier architecture: a relational database (PostgreSQL or Oracle), a Java application server running in an Eclipse Equinox OSGi container, and a ZK-based web client.
  • The OSGi framework enables modular plugin development where extensions are self-contained bundles that can be deployed, updated, and removed at runtime without modifying core code.
  • The Application Dictionary stores application metadata in the database, enabling model-driven development where windows, fields, and business rules can be configured without writing code.
  • The ZK Framework provides a server-centric Ajax web UI that delivers a desktop-like experience through standard web browsers.
  • The code is organized into persistence (PO classes), model/business logic (document processing, validation), and UI (ZK components) layers.
  • A user request flows from browser to ZK engine, then to the Application Dictionary for metadata, through model validation and business logic, to database persistence, and back.

What’s Next

Now that you understand how iDempiere is structured internally, it is time to get hands-on. In the next lesson, you will install iDempiere on your own machine — either through a traditional installation on Linux or using Docker — and verify that everything is running correctly by logging in for the first time.

繁體中文

概覽

  • 您將學到:
    • iDempiere 的三層式架構:資料庫層、應用程式伺服器層和網頁客戶端層
    • OSGi 和 Eclipse Equinox 容器如何實現模組化的外掛開發
    • Application Dictionary 在模型驅動開發中的角色,以及請求如何從瀏覽器流經到資料庫再返回
  • 先備知識:第 1 課 — 什麼是 iDempiere?
  • 預估閱讀時間:18 分鐘

簡介

無論您計劃為企業實施系統、開發外掛來擴展功能,還是僅僅管理現有的安裝,了解 iDempiere 的架構都是必不可少的。iDempiere 創始人所做的架構決策 — 採用 OSGi 模組化、ZK 網頁框架,以及保留其 Compiere 傳承的 Application Dictionary — 決定了系統的行為方式、擴展方式和擴展能力。

在本課中,我們將逐層剖析 iDempiere 的架構。到課程結束時,您將對所有部分如何組合在一起有清晰的心智模型 — 從使用者在瀏覽器中點擊按鈕的那一刻到結果顯示在螢幕上的那一刻。

三層式架構

iDempiere 遵循經典的三層式架構模式,將職責分離到不同的層中。這種分離促進了可維護性、可擴展性,以及在不干擾其他層的情況下修改某一層的能力。

第一層:資料庫

iDempiere 的基礎是關聯式資料庫,它作為所有業務資料、設定和中繼資料的持久性資料儲存。iDempiere 支援兩種資料庫系統:

  • PostgreSQL(14 版或更高版本)— 社群中最主要且最廣泛使用的選項。PostgreSQL 是免費的、開源的,提供出色的效能、可靠性和標準合規性。
  • Oracle Database(12c 版或更高版本)— 支援擁有現有 Oracle 基礎設施或授權的組織。Oracle 支援自最初的 Compiere 時代就是系統的一部分。

資料庫儲存的遠不止交易資料(訂單、發票、付款)。它還儲存 Application Dictionary — 定義應用程式本身的中繼資料。AD_WindowAD_TabAD_FieldAD_ColumnAD_Table 等表描述了使用者介面中每個視窗、分頁和欄位的結構。這意味著資料庫既是資料儲存庫,也是應用程式定義儲存庫。

iDempiere 中的關鍵資料庫概念包括:

  • AD_Client_ID 和 AD_Org_ID:幾乎每個表都包含這些欄位,在資料庫層級實現多租戶資料隔離和組織分段。
  • IsActive 標記:記錄透過設定 IsActive = 'N' 進行軟刪除而非物理移除,保留稽核軌跡和參照完整性。
  • Created/Updated 時間戳記和 CreatedBy/UpdatedBy:每筆記錄都追蹤其建立和最後修改的時間以及操作使用者,提供內建的稽核軌跡。

第二層:應用程式伺服器

中間層是 iDempiere 應用程式伺服器,這是一個在 Eclipse Equinox OSGi 容器中執行的 Java 程序。業務邏輯在此執行:處理文件、執行工作流程、進行計算、執行驗證規則,以及協調資料庫和使用者介面之間的通訊。

應用程式伺服器處理:

  • 業務邏輯執行:模型類別(對應資料庫表的 Java POJO)包含驗證、處理和完成業務文件的邏輯。
  • 流程排程:背景流程和排程任務(如每夜的記帳處理或自動報表產生)由伺服器的排程器管理。
  • 工作階段管理:使用者認證、工作階段追蹤和安全性上下文(使用者正在操作的客戶端、組織、角色和倉庫)在此層維護。
  • 快取:應用程式伺服器快取 Application Dictionary 中繼資料、參考資料和頻繁存取的設定,以減少資料庫查詢並提高回應時間。

第三層:網頁客戶端

展示層是建構在 ZK Framework 上的網頁使用者介面,ZK Framework 是一個基於 Ajax 的 Java 網頁應用程式框架。使用者透過標準網頁瀏覽器存取 iDempiere — 不需要安裝任何客戶端軟體。

ZK Framework 使用伺服器端中心的程式設計模型:UI 元件在伺服器端以 Java 建立和管理,ZK 使用 Ajax 呼叫自動同步伺服器和瀏覽器之間的狀態。這意味著 iDempiere 開發者編寫 Java 程式碼來定義 UI 行為,ZK 負責所有 HTML、CSS 和 JavaScript 的產生和通訊。

網頁客戶端的主要特性:

  • 無需外掛或 applet:介面可在任何現代網頁瀏覽器(Chrome、Firefox、Edge、Safari)中執行。
  • 類桌面體驗:ZK 提供豐富的 UI 元件 — 樹狀結構、網格、分頁、對話框、拖放 — 感覺更像桌面應用程式而非傳統網頁。
  • 回應式通訊:ZK 使用 Ajax 僅傳送增量 UI 更新,而非重新載入整個頁面,從而帶來流暢、回應迅速的使用者體驗。

OSGi 和 Eclipse Equinox 容器

採用 OSGi 是 iDempiere 與其前身(Compiere 和 ADempiere)的根本區別。對於任何想要擴展或自訂 iDempiere 的人來說,了解 OSGi 至關重要。

什麼是 OSGi?

OSGi(Open Services Gateway initiative)是 Java 的模組化框架。它定義了一個 bundle(模組)系統,可以獨立開發、部署、啟動、停止、更新和解除安裝 — 全部無需重新啟動應用程式。每個 bundle 都有明確的聲明,說明它匯出哪些套件(提供給其他 bundle)和匯入哪些套件(需要來自其他 bundle)。

將 OSGi bundle 想像成智慧型手機上的應用程式:每個都是自包含的,聲明它需要什麼,可以安裝或移除而不影響手機的作業系統或其他應用程式。

iDempiere 如何使用 OSGi

iDempiere 在 Eclipse Equinox OSGi 容器中執行,這與驅動 Eclipse IDE 的 OSGi 執行環境相同。iDempiere 核心本身由多個 OSGi bundle 組成:

  • org.adempiere.base — 核心業務邏輯、模型類別和工具函式
  • org.adempiere.ui.zk — 基於 ZK 的網頁使用者介面
  • org.adempiere.server — 伺服器流程、排程器和背景任務
  • org.adempiere.report.jasper — JasperReports 整合用於格式化報表
  • org.adempiere.install — 安裝和設定工具

開發者為 iDempiere 建立外掛時,會建立新的 OSGi bundle,聲明對核心 bundle 的依賴關係,並透過定義良好的擴展點註冊擴展。最重要的擴展機制包括:

  • Model Validator:外掛可以註冊在記錄儲存、刪除或文件處理之前或之後觸發的監聽器。這是新增自訂業務邏輯的主要機制。
  • Callout:外掛可以註冊欄位層級的事件處理器,在使用者更改表單欄位值時執行,實現即時欄位計算和自動填充。
  • Process 類別:外掛可以新增出現在 iDempiere 選單中或可附加到工具列按鈕的新可執行流程。
  • Form 類別:外掛可以定義用於特殊資料輸入或顯示需求的自訂使用者介面表單。
  • Event Handler:使用 OSGi 的事件管理服務,外掛可以非同步地訂閱和回應系統事件。

為什麼 OSGi 很重要

OSGi 架構提供了幾個關鍵好處:

  1. 清晰分離:自訂程式碼存在於獨立的外掛 bundle 中,永遠不會混入核心原始碼。這使升級變得容易得多 — 您更新核心,您的外掛繼續運作(假設它們依賴的 API 沒有改變)。
  2. 執行時部署:可以在 iDempiere 執行時安裝和更新外掛。在許多情況下,您不需要重新啟動伺服器來啟動新外掛。
  3. 依賴管理:OSGi 強制執行明確的依賴聲明,防止 classpath 衝突並確保 bundle 以正確的順序載入。
  4. 隔離:每個 bundle 都有自己的類別載入器,防止外掛之間的非預期互動,降低一個外掛的程式碼破壞另一個外掛的風險。

外掛 Bundle 結構

典型的 iDempiere 外掛 bundle 結構如下:

com.example.myplugin/
├── META-INF/
│   └── MANIFEST.MF          # OSGi bundle 中繼資料(名稱、版本、依賴)
├── src/
│   └── com/example/myplugin/
│       ├── Activator.java    # Bundle 生命週期管理
│       ├── MyModelValidator.java
│       └── MyProcess.java
├── OSGI-INF/
│   └── component.xml         # OSGi Declarative Services 元件定義
├── plugin.xml                # Eclipse 擴展點註冊
└── build.properties          # 建構設定

MANIFEST.MF 檔案是最重要的描述檔。它聲明 bundle 的符號名稱、版本、匯入的套件和匯出的套件:

Bundle-SymbolicName: com.example.myplugin
Bundle-Version: 1.0.0
Require-Bundle: org.adempiere.base;bundle-version="12.0.0"
Import-Package: org.compiere.model,
 org.compiere.process,
 org.compiere.util

Application Dictionary:模型驅動開發

Application Dictionary(AD)是 iDempiere 可設定性的核心。它是資料庫中的一組中繼資料表,描述應用程式結構和行為的每個方面。

字典如何運作

當使用者在 iDempiere 中開啟一個視窗時,系統不會載入寫死的 Java 畫面。而是查詢 Application Dictionary 來確定:

  1. 視窗包含哪些分頁(來自 AD_Tab
  2. 每個分頁顯示哪些欄位(來自 AD_Field,連結到 AD_Column
  3. 每個分頁綁定到哪個(來自 AD_Table
  4. 哪些驗證規則適用於每個欄位(來自 AD_Val_Rule
  5. 當欄位值改變時觸發哪些 callout(來自 AD_Column.Callout
  6. 哪些顯示邏輯控制欄位可見性(來自 AD_Field.DisplayLogic
  7. 新記錄要填充哪些預設值(來自 AD_Column.DefaultValue

ZK UI 層讀取此中繼資料並動態產生適當的使用者介面元件。這就是為什麼您可以為表新增一個欄位、在 Application Dictionary 中定義它,並立即在使用者介面中看到它 — 無需撰寫任何 Java 或 JavaScript 程式碼。

關鍵字典表

用途
AD_Table 定義在系統中註冊的資料庫表
AD_Column 定義表中的欄位,包括資料類型、預設值、驗證和 callout 參照
AD_Window 定義應用程式視窗(頂層 UI 容器)
AD_Tab 定義視窗中的分頁,每個分頁綁定到一個表
AD_Field 定義分頁中的個別欄位,控制顯示順序、唯讀邏輯和顯示邏輯
AD_Process 定義可執行流程(報表、批次作業、動作)
AD_Menu 定義導覽選單樹
AD_Reference 定義下拉選單、搜尋查詢和其他參照類型
AD_Val_Rule 定義基於 SQL 的驗證規則,動態過濾下拉選單值
AD_Workflow 定義文件核准工作流程和自動化流程

模型驅動開發的力量

Application Dictionary 方法意味著 iDempiere 自訂的很大一部分可以由功能顧問透過應用程式自身的使用者介面執行,無需撰寫程式碼。常見的字典層級自訂包括:

  • 在現有視窗中新增欄位
  • 為自訂表建立全新的視窗、分頁和欄位
  • 定義控制下拉選單中顯示哪些值的驗證規則
  • 設定顯示邏輯以根據其他欄位值顯示或隱藏欄位
  • 使用上下文變數和 SQL 表達式設定預設值
  • 建構具有核准步驟和自動操作的文件工作流程

關鍵層:持久化、模型和 UI

在應用程式伺服器內,iDempiere 的程式碼組織為三個概念層:

持久化層

持久化層處理與資料庫的所有通訊。iDempiere 使用自己的持久化框架(而非像 Hibernate 這樣的外部 ORM),建構在 PO(Persistent Object)基礎類別之上。每個業務實體 — 訂單、發票、產品、業務夥伴 — 都由一個繼承 PO 的 Java 類別表示。這些模型類別主要從 Application Dictionary 自動產生,具有 getC_Order_ID()setDateOrdered()getDocStatus() 等方法,直接對應資料庫欄位。

PO 類別提供:

  • 自動產生 SELECT、INSERT、UPDATE 和 DELETE 操作的 SQL
  • 透明處理多租戶過濾(AD_Client_ID)
  • 用於業務邏輯的儲存前和儲存後事件掛鉤
  • 用於稽核軌跡的變更記錄
  • 快取頻繁存取的記錄

模型/業務邏輯層

模型層包含操作持久物件的業務邏輯。對於文件(訂單、發票、付款、出貨),這包括管理文件生命週期的文件處理引擎:草稿 → 處理中 → 已完成 → 已關閉(或作廢/沖銷)。模型層強制執行業務規則 — 例如,確保在沒有有效稅務設定的情況下不能完成發票,或者如果倉庫設定為不允許負庫存,庫存不能為負。

模型層中的關鍵類別包括:

  • MOrderMInvoiceMPaymentMInOut — 具有處理邏輯的文件模型類別
  • DocAction — 定義文件處理生命週期的介面
  • Doc 及其子類別 — 從業務文件產生總帳分錄的記帳引擎
  • MProcess — 流程執行框架

UI 層

UI 層建構在 ZK Framework 之上,負責在瀏覽器中呈現使用者介面。關鍵元件包括:

  • ADWindow:通用視窗渲染器,讀取 Application Dictionary 中繼資料並動態建構 UI
  • ADForm:需要超越字典所能描述的特殊 UI 的自訂表單基礎類別
  • GridTable / GridField:將 UI 元件連接到底層模型物件的資料綁定層
  • WEditor:不同欄位類型(文字、數字、日期、查詢等)的編輯器元件

請求如何在 iDempiere 中流動

為了將所有內容串聯起來,讓我們追蹤當使用者開啟銷售訂單視窗並儲存新訂單時發生的事情:

  1. 瀏覽器 → ZK 引擎:使用者在選單中點擊「銷售訂單」。瀏覽器向伺服器端 ZK 引擎發送 Ajax 請求。
  2. ZK 引擎 → Application Dictionary:ZK ADWindow 元件查詢 Application Dictionary 表(AD_WindowAD_TabAD_Field)以確定視窗結構。
  3. 字典 → UI 渲染:根據字典中繼資料,ZK 動態建立適當的 UI 元件(分頁、欄位、按鈕、網格)並將渲染的 HTML/JavaScript 傳回瀏覽器。
  4. 使用者輸入資料:當使用者填寫欄位時,callout 在伺服器端觸發(透過 Ajax)執行即時計算 — 例如,選擇業務夥伴會自動填充付款條件、價格表和送貨地址。
  5. 儲存請求:當使用者點擊儲存時,Ajax 請求將欄位值傳送到伺服器。
  6. 模型驗證:MOrder 模型類別驗證資料 — 檢查必填欄位、驗證參照完整性、執行外掛註冊的任何 Model Validator。
  7. 持久化:PO.saveEx() 方法在交易中產生適當的 SQL INSERT 或 UPDATE 語句並對資料庫執行。
  8. 回應:成功後,伺服器更新 UI 狀態,ZK 向瀏覽器傳送 Ajax 回應,確認儲存、更新狀態指示器並重新整理任何計算欄位。

對於簡單操作,這整個往返通常在毫秒內完成,展示了伺服器中心 ZK 模型與 iDempiere 快取層結合的效率。

重點摘要

  • iDempiere 使用三層式架構:關聯式資料庫(PostgreSQL 或 Oracle)、在 Eclipse Equinox OSGi 容器中執行的 Java 應用程式伺服器,以及基於 ZK 的網頁客戶端。
  • OSGi 框架實現模組化外掛開發,擴展是自包含的 bundle,可以在執行時部署、更新和移除,而無需修改核心程式碼。
  • Application Dictionary 將應用程式中繼資料儲存在資料庫中,實現模型驅動開發,其中視窗、欄位和業務規則可以在不撰寫程式碼的情況下進行設定。
  • ZK Framework 提供伺服器中心的 Ajax 網頁 UI,透過標準網頁瀏覽器提供類桌面體驗。
  • 程式碼組織為持久化(PO 類別)、模型/業務邏輯(文件處理、驗證)和 UI(ZK 元件)層。
  • 使用者請求從瀏覽器流向 ZK 引擎,然後到 Application Dictionary 獲取中繼資料,經過模型驗證和業務邏輯,到資料庫持久化,再返回。

下一步

現在您了解了 iDempiere 的內部結構,是時候親自動手了。在下一課中,您將在自己的機器上安裝 iDempiere — 透過在 Linux 上的傳統安裝或使用 Docker — 並透過首次登入來驗證一切是否正常運作。

日本語

概要

  • 学習内容:
    • iDempiere の三層アーキテクチャ:データベース層、アプリケーションサーバー層、Web クライアント層
    • OSGi と Eclipse Equinox コンテナがモジュラーなプラグインベースの開発をどのように実現するか
    • モデル駆動開発における Application Dictionary の役割と、リクエストがブラウザからデータベースへ、そして戻ってくるまでの流れ
  • 前提条件:第1課 — iDempiereとは?
  • 推定読了時間:18分

はじめに

ビジネスのためにシステムを導入する場合でも、機能を拡張するプラグインを開発する場合でも、既存のインストールを管理する場合でも、iDempiere のアーキテクチャを理解することは不可欠です。iDempiere の創設者が行ったアーキテクチャ上の決定 — OSGi モジュール性の採用、ZK Web フレームワーク、Compiere の遺産である Application Dictionary の保持 — が、システムの動作方法、拡張方法、スケーリング方法を定義しています。

このレッスンでは、iDempiere のアーキテクチャをレイヤーごとに解剖します。レッスンの終わりには、すべてのピースがどのように組み合わさるかの明確なメンタルモデルが得られます — ユーザーがブラウザでボタンをクリックした瞬間から、結果が画面に表示される瞬間までです。

三層アーキテクチャ

iDempiere は、責任が異なるレイヤーに分離される古典的な三層アーキテクチャパターンに従っています。この分離により、保守性、スケーラビリティ、そして他の層を中断することなく一つの層を変更する能力が促進されます。

第1層:データベース

iDempiere の基盤にはリレーショナルデータベースがあり、すべてのビジネスデータ、設定、メタデータの永続的なデータストアとして機能します。iDempiere は2つのデータベースシステムをサポートしています:

  • PostgreSQL(バージョン14以上)— コミュニティで最も主要で広く使用されているオプション。PostgreSQL は無料のオープンソースで、優れたパフォーマンス、信頼性、標準準拠を提供します。
  • Oracle Database(バージョン12c以上)— 既存の Oracle インフラストラクチャやライセンスを持つ組織向けにサポートされています。Oracle サポートは、オリジナルの Compiere 時代からシステムの一部でした。

データベースには、トランザクションデータ(注文、請求書、支払い)だけでなく、それ以上のものが格納されています。Application Dictionary — アプリケーション自体を定義するメタデータも格納されています。AD_WindowAD_TabAD_FieldAD_ColumnAD_Table などのテーブルが、ユーザーインターフェースのすべてのウィンドウ、タブ、フィールドの構造を記述します。これは、データベースがデータストアであると同時にアプリケーション定義リポジトリでもあることを意味します。

iDempiere の主要なデータベース概念には以下が含まれます:

  • AD_Client_ID と AD_Org_ID:ほぼすべてのテーブルにこれらのカラムが含まれ、データベースレベルでのマルチテナントデータ分離と組織セグメンテーションを実現します。
  • IsActive フラグ:レコードは物理的に削除されるのではなく、IsActive = 'N' に設定することで論理削除され、監査証跡と参照整合性が保持されます。
  • Created/Updated タイムスタンプと CreatedBy/UpdatedBy:すべてのレコードが、いつ作成され、最後に変更されたか、どのユーザーによるものかを追跡し、組み込みの監査証跡を提供します。

第2層:アプリケーションサーバー

中間層は iDempiere アプリケーションサーバーで、Eclipse Equinox OSGi コンテナ内で実行される Java ベースのプロセスです。ここでビジネスロジックが実行されます:ドキュメントの処理、ワークフローの実行、計算の実行、検証ルールの適用、データベースとユーザーインターフェース間の調整です。

アプリケーションサーバーは以下を処理します:

  • ビジネスロジックの実行:モデルクラス(データベーステーブルに対応する Java POJO)に、ビジネスドキュメントの検証、処理、完了のロジックが含まれています。
  • プロセスのスケジューリング:バックグラウンドプロセスとスケジュールされたタスク(夜間の会計処理や自動レポート生成など)は、サーバーのスケジューラーによって管理されます。
  • セッション管理:ユーザー認証、セッション追跡、セキュリティコンテキスト(ユーザーがどのクライアント、組織、ロール、倉庫で操作しているか)がこの層で維持されます。
  • キャッシュ:アプリケーションサーバーは Application Dictionary メタデータ、参照データ、頻繁にアクセスされる設定をキャッシュし、データベースクエリを最小限に抑え、応答時間を改善します。

第3層:Web クライアント

プレゼンテーション層は、ZK Framework 上に構築された Web ベースのユーザーインターフェースです。ZK Framework は Java 向けの Ajax ベースの Web アプリケーションフレームワークです。ユーザーは標準の Web ブラウザを通じて iDempiere にアクセスします — クライアント側のソフトウェアインストールは不要です。

ZK Framework はサーバー中心のプログラミングモデルを使用します:UI コンポーネントはサーバー側で Java により作成・管理され、ZK が Ajax 呼び出しを使用してサーバーとブラウザ間の状態を自動的に同期します。これにより、iDempiere 開発者は Java コードで UI の動作を定義し、ZK がすべての HTML、CSS、JavaScript の生成と通信を処理します。

Web クライアントの主な特徴:

  • プラグインやアプレット不要:インターフェースは任意のモダンな Web ブラウザ(Chrome、Firefox、Edge、Safari)で動作します。
  • デスクトップライクな体験:ZK はリッチな UI コンポーネント — ツリー、グリッド、タブ、ダイアログ、ドラッグ&ドロップ — を提供し、従来の Web ページよりもデスクトップアプリケーションに近い感覚です。
  • レスポンシブな通信:ZK は Ajax を使用してページ全体をリロードするのではなく、インクリメンタルな UI 更新のみを送信し、スムーズでレスポンシブなユーザー体験を実現します。

OSGi と Eclipse Equinox コンテナ

OSGi の採用は、iDempiere をその前身(Compiere と ADempiere)と根本的に区別するものです。iDempiere を拡張またはカスタマイズしたい人にとって、OSGi の理解は不可欠です。

OSGi とは?

OSGi(Open Services Gateway initiative)は Java のモジュラリティフレームワークです。アプリケーションを再起動することなく、独立して開発、デプロイ、起動、停止、更新、アンインストールできるバンドル(モジュール)のシステムを定義します。各バンドルは、エクスポートするパッケージ(他のバンドルに提供するもの)とインポートするパッケージ(他のバンドルから必要とするもの)を明示的に宣言します。

OSGi バンドルをスマートフォンのアプリに例えて考えてみてください:各アプリは自己完結しており、必要なものを宣言し、電話のオペレーティングシステムや他のアプリに影響を与えずにインストールまたは削除できます。

iDempiere での OSGi の活用方法

iDempiere は Eclipse Equinox OSGi コンテナ内で実行されます。これは Eclipse IDE を動かしているのと同じ OSGi ランタイムです。iDempiere のコア自体が複数の OSGi バンドルで構成されています:

  • org.adempiere.base — コアビジネスロジック、モデルクラス、ユーティリティ関数
  • org.adempiere.ui.zk — ZK ベースの Web ユーザーインターフェース
  • org.adempiere.server — サーバープロセス、スケジューラー、バックグラウンドタスク
  • org.adempiere.report.jasper — フォーマット済みレポートのための JasperReports 統合
  • org.adempiere.install — インストールおよびセットアップユーティリティ

開発者が iDempiere 用のプラグインを作成する際、コアバンドルへの依存関係を宣言し、明確に定義された拡張ポイントを通じて拡張を登録する新しい OSGi バンドルを作成します。最も重要な拡張メカニズムには以下が含まれます:

  • Model Validator:プラグインは、レコードの保存、削除、ドキュメント処理の前後に発火するリスナーを登録できます。これはカスタムビジネスロジックを追加するための主要なメカニズムです。
  • Callout:プラグインは、ユーザーがフォームフィールドの値を変更したときに実行されるフィールドレベルのイベントハンドラーを登録でき、リアルタイムのフィールド計算と自動入力を可能にします。
  • Process クラス:プラグインは、iDempiere メニューに表示されるか、ツールバーボタンにアタッチできる新しい実行可能プロセスを追加できます。
  • Form クラス:プラグインは、特殊なデータ入力や表示のニーズに対応するカスタムユーザーインターフェースフォームを定義できます。
  • Event Handler:OSGi のイベント管理サービスを使用して、プラグインはシステムイベントを非同期でサブスクライブし、反応できます。

OSGi が重要な理由

OSGi アーキテクチャはいくつかの重要な利点を提供します:

  1. 明確な分離:カスタムコードは個別のプラグインバンドルに存在し、コアソースコードに混入することはありません。これによりアップグレードが劇的に容易になります — コアを更新しても、プラグインは動作し続けます(依存する API が変更されていない限り)。
  2. ランタイムデプロイメント:iDempiere の実行中にプラグインをインストールおよび更新できます。多くの場合、新しいプラグインを有効にするためにサーバーを再起動する必要はありません。
  3. 依存関係管理:OSGi は明示的な依存関係宣言を強制し、クラスパスの競合を防ぎ、バンドルが正しい順序でロードされることを保証します。
  4. 分離:各バンドルには独自のクラスローダーがあり、プラグイン間の意図しない相互作用を防ぎ、あるプラグインのコードが別のプラグインを壊すリスクを軽減します。

プラグインバンドル構造

典型的な iDempiere プラグインバンドルは以下のような構造です:

com.example.myplugin/
├── META-INF/
│   └── MANIFEST.MF          # OSGi バンドルメタデータ(名前、バージョン、依存関係)
├── src/
│   └── com/example/myplugin/
│       ├── Activator.java    # バンドルライフサイクル管理
│       ├── MyModelValidator.java
│       └── MyProcess.java
├── OSGI-INF/
│   └── component.xml         # OSGi Declarative Services コンポーネント定義
├── plugin.xml                # Eclipse 拡張ポイント登録
└── build.properties          # ビルド設定

MANIFEST.MF ファイルは最も重要な記述子です。バンドルのシンボリック名、バージョン、インポートするパッケージ、エクスポートするパッケージを宣言します:

Bundle-SymbolicName: com.example.myplugin
Bundle-Version: 1.0.0
Require-Bundle: org.adempiere.base;bundle-version="12.0.0"
Import-Package: org.compiere.model,
 org.compiere.process,
 org.compiere.util

Application Dictionary:モデル駆動開発

Application Dictionary(AD)は iDempiere の設定可能性の中核です。データベース内のメタデータテーブルのセットで、アプリケーションの構造と動作のあらゆる側面を記述します。

ディクショナリの仕組み

ユーザーが iDempiere でウィンドウを開くとき、システムはハードコードされた Java 画面をロードしません。代わりに、Application Dictionary を照会して以下を決定します:

  1. ウィンドウにどのタブが含まれるか(AD_Tab から)
  2. 各タブがどのフィールドを表示するか(AD_Field から、AD_Column にリンク)
  3. 各タブがどのテーブルにバインドされているか(AD_Table から)
  4. 各フィールドにどの検証ルールが適用されるか(AD_Val_Rule から)
  5. フィールド値が変更されたときにどの Callout が発火するか(AD_Column.Callout から)
  6. どの表示ロジックがフィールドの表示/非表示を制御するか(AD_Field.DisplayLogic から)
  7. 新しいレコードにどのデフォルト値を設定するか(AD_Column.DefaultValue から)

ZK UI レイヤーはこのメタデータを読み取り、適切なユーザーインターフェースコンポーネントを動的に生成します。テーブルに新しいカラムを追加し、Application Dictionary で定義すると、Java や JavaScript のコードを書くことなく、すぐにユーザーインターフェースに表示されるのはこのためです。

主要なディクショナリテーブル

テーブル 目的
AD_Table システムに登録されたデータベーステーブルを定義
AD_Column テーブル内のカラムを定義(データ型、デフォルト値、検証、Callout 参照を含む)
AD_Window アプリケーションウィンドウ(トップレベルの UI コンテナ)を定義
AD_Tab ウィンドウ内のタブを定義(各タブはテーブルにバインド)
AD_Field タブ内の個々のフィールドを定義(表示順序、読み取り専用ロジック、表示ロジックを制御)
AD_Process 実行可能なプロセス(レポート、バッチジョブ、アクション)を定義
AD_Menu ナビゲーションメニューツリーを定義
AD_Reference ドロップダウンリスト、検索ルックアップ、その他の参照タイプを定義
AD_Val_Rule ドロップダウン値を動的にフィルタリングする SQL ベースの検証ルールを定義
AD_Workflow ドキュメント承認ワークフローと自動化プロセスを定義

モデル駆動開発の力

Application Dictionary のアプローチにより、iDempiere カスタマイズの大部分は、コードを書くことなく、アプリケーション自体のユーザーインターフェースを通じて機能コンサルタントが実行できます。一般的なディクショナリレベルのカスタマイズには以下が含まれます:

  • 既存のウィンドウに新しいフィールドを追加
  • カスタムテーブル用の全く新しいウィンドウ、タブ、フィールドの作成
  • ドロップダウンリストに表示される値を制御する検証ルールの定義
  • 他のフィールド値に基づいてフィールドを表示/非表示にする表示ロジックの設定
  • コンテキスト変数と SQL 式を使用したデフォルト値の設定
  • 承認ステップと自動アクションを含むドキュメントワークフローの構築

主要レイヤー:永続化、モデル、UI

アプリケーションサーバー内で、iDempiere のコードは3つの概念的なレイヤーに組織されています:

永続化レイヤー

永続化レイヤーは、データベースとのすべての通信を処理します。iDempiere は(Hibernate のような外部 ORM ではなく)PO(Persistent Object)基底クラスを中心に構築された独自の永続化フレームワークを使用します。すべてのビジネスエンティティ — 注文、請求書、商品、取引先 — は、PO を継承する Java クラスで表現されます。これらのモデルクラスは Application Dictionary から大部分が自動生成され、getC_Order_ID()setDateOrdered()getDocStatus() などのメソッドがデータベースカラムに直接対応しています。

PO クラスは以下を提供します:

  • SELECT、INSERT、UPDATE、DELETE 操作の SQL 自動生成
  • マルチテナントフィルタリング(AD_Client_ID)の透過的な処理
  • ビジネスロジックのための保存前・保存後イベントフック
  • 監査証跡のための変更ログ
  • 頻繁にアクセスされるレコードのキャッシュ

モデル/ビジネスロジックレイヤー

モデルレイヤーには、永続オブジェクトに対して操作するビジネスロジックが含まれています。ドキュメント(注文、請求書、支払い、出荷)については、ドキュメントライフサイクルを管理するドキュメント処理エンジンが含まれます:下書き → 処理中 → 完了 → クローズ(または取消/反転)。モデルレイヤーはビジネスルールを強制します — たとえば、有効な税設定がない場合に請求書を完了できないようにしたり、倉庫がマイナス在庫を許可しないように設定されている場合に在庫がマイナスにならないようにしたりします。

モデルレイヤーの主要なクラスには以下が含まれます:

  • MOrderMInvoiceMPaymentMInOut — 処理ロジックを持つドキュメントモデルクラス
  • DocAction — ドキュメント処理ライフサイクルを定義するインターフェース
  • Doc とそのサブクラス — ビジネスドキュメントから GL 仕訳を生成する会計エンジン
  • MProcess — プロセス実行フレームワーク

UI レイヤー

UI レイヤーは ZK Framework 上に構築され、ブラウザでのユーザーインターフェースのレンダリングを担当します。主要なコンポーネントには以下が含まれます:

  • ADWindow:Application Dictionary メタデータを読み取り、UI を動的に構築する汎用ウィンドウレンダラー
  • ADForm:ディクショナリで記述できる範囲を超えた特殊な UI を必要とするカスタムフォームの基底クラス
  • GridTable / GridField:UI コンポーネントを基盤となるモデルオブジェクトに接続するデータバインディングレイヤー
  • WEditor:異なるフィールドタイプ(テキスト、数値、日付、ルックアップなど)用のエディターコンポーネント

リクエストが iDempiere をどのように流れるか

すべてをまとめるために、ユーザーが受注ウィンドウを開き、新しい注文を保存するときに何が起こるかを追跡してみましょう:

  1. ブラウザ → ZK エンジン:ユーザーがメニューで「受注」をクリックします。ブラウザがサーバー側の ZK エンジンに Ajax リクエストを送信します。
  2. ZK エンジン → Application Dictionary:ZK の ADWindow コンポーネントが Application Dictionary テーブル(AD_WindowAD_TabAD_Field)を照会してウィンドウ構造を決定します。
  3. ディクショナリ → UI レンダリング:ディクショナリのメタデータに基づいて、ZK は適切な UI コンポーネント(タブ、フィールド、ボタン、グリッド)を動的に作成し、レンダリングされた HTML/JavaScript をブラウザに返送します。
  4. ユーザーがデータを入力:ユーザーがフィールドに入力するにつれて、サーバー側で Callout が(Ajax を通じて)発火し、リアルタイム計算を実行します — たとえば、取引先を選択すると支払条件、価格表、配送先住所が自動的に設定されます。
  5. 保存リクエスト:ユーザーが保存をクリックすると、Ajax リクエストがフィールド値をサーバーに送信します。
  6. モデル検証:MOrder モデルクラスがデータを検証します — 必須フィールドのチェック、参照整合性の確認、プラグインから登録された Model Validator の実行。
  7. 永続化:PO.saveEx() メソッドが、トランザクション内で適切な SQL INSERT または UPDATE 文を生成し、データベースに対して実行します。
  8. レスポンス:成功すると、サーバーが UI 状態を更新し、ZK がブラウザに保存の確認、ステータスインジケーターの更新、計算フィールドのリフレッシュを含む Ajax レスポンスを送信します。

この往復全体は、単純な操作では通常ミリ秒単位で完了し、サーバー中心の ZK モデルと iDempiere のキャッシュレイヤーの組み合わせの効率性を示しています。

まとめ

  • iDempiere は三層アーキテクチャを使用しています:リレーショナルデータベース(PostgreSQL または Oracle)、Eclipse Equinox OSGi コンテナで実行される Java アプリケーションサーバー、ZK ベースの Web クライアント。
  • OSGi フレームワークにより、拡張が自己完結型のバンドルとしてモジュラーなプラグイン開発が可能になり、コアコードを変更することなくランタイムでデプロイ、更新、削除できます。
  • Application Dictionary はアプリケーションメタデータをデータベースに格納し、コードを書くことなくウィンドウ、フィールド、ビジネスルールを設定できるモデル駆動開発を実現します。
  • ZK Framework は、標準の Web ブラウザを通じてデスクトップライクな体験を提供するサーバー中心の Ajax Web UI を提供します。
  • コードは永続化(PO クラス)、モデル/ビジネスロジック(ドキュメント処理、検証)、UI(ZK コンポーネント)のレイヤーに組織されています。
  • ユーザーリクエストはブラウザから ZK エンジンへ、次に Application Dictionary へメタデータを取得し、モデル検証とビジネスロジックを通じ、データベースの永続化へ、そして戻ってきます。

次のステップ

iDempiere の内部構造を理解した今、実際に手を動かす時です。次のレッスンでは、Linux での従来のインストールまたは Docker を使用して、自分のマシンに iDempiere をインストールし、初めてのログインですべてが正しく動作していることを確認します。

You Missed