I. Overview
A typical business module is split into Maven projects by responsibility: api and core are the standard layers, and view is optional. When you depend on another business module (or a platform built-in module), keep two things aligned:
- Which Maven layer you depend on: whether this process has the other module's models, implementations, and built-in XML views shipped with the code.
- Whether
pamirs.boot.moduleslists that module: whether this process installs and starts the module locally.
These two must match. Depending only on api while listing the module in the startup list, or depending on core without listing it, are common causes of startup and remote-call failures.
This article uses business module demo (xxx-demo-api / xxx-demo-core / xxx-demo-view) as the main example. Platform built-in modules (such as file, message, and eip) are only contrasts; the layering rules are the same.
For mandatory constraints in distributed invocation, see Project Integration: How Oinone Supports Building Distributed Projects.
II. What Each Package Contains
(I) api package (required)
The api package is the module's public contract. It usually contains:
- The module definition (
PamirsModule, plus@ModuledependenciesandpackagePrefix) - Models, enums, and constants
- Function / Action interface declarations (implementations live in core)
- Types that other modules need at compile time
Who depends on api:
- The current business module's api project: when models reference the other module's models, or when
@Module.dependenciesmust declare the other module. - The caller boot project in a distributed setup: this process does not run the other module's implementation and only uses models and interfaces for remote calls.
Depending only on api does not install that module's runtime in this process (no local Function implementations or lifecycle initialization).
(II) core package (required when this process provides the module)
The core package is the module's runtime implementation. It usually contains:
- Function / Action implementations
- Install, upgrade, and post-boot initialization
- SPI / extension implementations
core transitively depends on api. The boot project should depend on core (not api only) when this process actually runs the module.
(III) view package (optional)
view is not required for every business module. Pages are designed and published in the UI Designer by default. Add a view package only when you need built-in XML views in code.
view typically stores:
- Built-in XML views (form, table, detail, and other DSL)
- Menus and UX metadata that go with those views
Benefits of adding view:
- The module can provide pages without the UI Designer.
- Views ship with the code. When module metadata is published to other environments, you do not need UI Designer export/import, which avoids page-metadata drift across environments.
view usually depends on api and cannot replace core. If view exists, the boot project that provides the module should add view in addition to core. If there is no view, depend on core only and keep pages in the UI Designer.
Built-in modules treat view the same way. For example, the integration module provides pamirs-eip2-view. Add it to the boot project when you need its built-in pages; depend only on pamirs-eip2-core when you only need integration runtime and pages are handled elsewhere.
III. Do Not Mix These Four “Dependencies”
| Where | Meaning | Typical usage |
|---|---|---|
| Maven dependency of the business api project | Compile-time access to the other module's models, interfaces, and module constants | Depend on xxx-other-api |
@Module.dependencies | Metadata declaration of which modules this module depends on | The other module's module code |
| Maven dependency of the boot project | Whether this JVM has the other module's implementation, and optionally built-in XML views | Depend on core to run it locally; add view for built-in XML views; depend on api only for remote calls |
pamirs.boot.modules | Which modules this process starts/installs locally | Only modules whose runtime this process actually provides |
@Module.dependencies and pamirs.boot.modules are not the same:
dependencieson the module definition: declare them whenever the business depends on the other module's models and interfaces, including on the distributed caller.modulesin the startup yml: only the modules this boot process installs. If the other module is served by another process, the caller yml must not list it.
The startup class @ComponentScan basePackages must also cover the other module's api package (for example pro.shushi.xxx.demo). Otherwise the module definition and models are not scanned. See Startup: Startup Dependency Errors.
IV. How to Configure pamirs.boot.modules
pamirs:
boot:
modules:
- base
- demo
# Add a module only when this process depends on that module's core2
3
4
5
6
Rules:
- Boot project depends on api only → do not list the module in
pamirs.boot.modules. - Boot project depends on core (this process provides the module) → must list it in
pamirs.boot.modules. - Adding view does not change the module code: add view when you have built-in XML views; omit it otherwise. The yml entry is still the same module.
pamirs.boot.modules is the low-code module startup list for this process. When modules live in different boot projects, calls between them go remote. See Module API - modules Low-code Module Startup List.
V. Common Combinations
All combinations below are about business modules. demo is the current module; other is another business module.
(I) Default split: api + core, pages in the UI Designer (most common)
Scenario: this boot process installs and runs demo. Pages are designed and published in the UI Designer.
| Project | Dependency |
|---|---|
xxx-demo-api | This module's contract |
| Boot project | xxx-demo-core (do not add xxx-demo-view) |
pamirs.boot.modules: includedemo- Pages: maintained in the UI Designer; sync to other environments via designer metadata export/import
This is the default split for a typical business module.
(II) Optional view: built-in XML views ship with the code
Scenario: demo pages are written in code, without the UI Designer, and you do not export/import pages when publishing to other environments.
| Project | Dependency |
|---|---|
xxx-demo-api | This module's contract |
xxx-demo-view | Built-in XML views and related menus |
| Boot project | xxx-demo-core, xxx-demo-view |
pamirs.boot.modules: includedemo(with or without view, the module is stilldemo)- Pages: installed into the target environment with the jar; no UI Designer metadata import
(III) This process also installs another business module (local provider)
Scenario: other also runs in this boot process.
| Project | Dependency |
|---|---|
xxx-demo-api | xxx-other-api |
| Boot project | xxx-other-core; add xxx-other-view if you need other's built-in XML views |
@Module.dependencies: declareotherpamirs.boot.modules: includeother
Built-in modules follow the same rule: to run the file module in this process, the boot project depends on pamirs-file2-core and yml lists file; add the corresponding view when you need its built-in pages.
(IV) Remote caller only (depend on the other module's api only)
Scenario: other is provided by another boot project; this process only references models and invokes Functions remotely.
| Project | Dependency |
|---|---|
xxx-demo-api | xxx-other-api |
| Boot project | xxx-other-api only (no core / view) |
@Module.dependencies: still declareother- Startup class scan: include the other module's api package
pamirs.boot.modules: do not listother
This process does not install other; calls go remote. That is the standard distributed Client setup. Built-in modules are the same: if you only invoke integration APIs and the integration service runs in another process, the boot project depends on pamirs-eip2-api only and yml must not list eip.
(V) Incorrect combinations
| Combination | Problem |
|---|---|
Boot project depends on api only, but pamirs.boot.modules lists the module | Startup requires a local install, but the classpath has no implementation. Typical error: the startup list contains a module that does not exist in the jars or the database |
Boot project depends on core, but pamirs.boot.modules does not list the module | Implementation classes may be picked up by Spring, but install/metadata loading as a startup module is incomplete |
| Treating view as required and splitting view for every business module | Pages can live in the UI Designer; an extra package has no benefit without built-in XML views |
| Boot project depends on view only, not core | view only provides built-in XML views, not runtime implementations |
@Module.dependencies omits the other module, but yml starts it | Metadata dependencies are incomplete; related models, permissions, and menus tend to break |
| Caller yml lists the provider module (distributed) | The caller tries to install the provider module locally, which conflicts with “api only, remote calls” |
VI. Configuration Examples
(I) Install this module locally (combination I in section V)
Boot project:
<dependency>
<groupId>pro.shushi.xxx</groupId>
<artifactId>xxx-demo-core</artifactId>
</dependency>2
3
4
pamirs:
boot:
modules:
- demo2
3
4
This module's definition:
@Module(
name = DemoModule.MODULE_NAME,
displayName = "Demo Module",
version = "1.0.0",
dependencies = {
ModuleConstants.MODULE_BASE
}
)
@Module.module(DemoModule.MODULE_MODULE)2
3
4
5
6
7
8
9
For built-in XML views (combination II), also add xxx-demo-view to the boot project. yml still lists only demo.
(II) Depending on another business module: local install vs remote call
Business api references the other contract:
<dependency>
<groupId>pro.shushi.xxx</groupId>
<artifactId>xxx-other-api</artifactId>
</dependency>2
3
4
@Module(
name = DemoModule.MODULE_NAME,
displayName = "Demo Module",
version = "1.0.0",
dependencies = {
ModuleConstants.MODULE_BASE,
OtherModule.MODULE_MODULE
}
)2
3
4
5
6
7
8
9
- Install
otherin this process: the boot project also depends onxxx-other-core(andxxx-other-viewif needed), and yml listsother. - Remote-call
otheronly: the boot project keepsxxx-other-apionly; yml must not listother; the startup class scan must include the other api package. See Dependency Relationships Between Business Models.
VII. Quick Reference
- api: contract (models + interfaces + module definition); required for a business module
- core: whether this process can provide the module's services
- view: optional; add it only for built-in XML views. Then pages do not depend on the UI Designer, and publishing to other environments does not need page-metadata export/import
pamirs.boot.modules: whether this process starts the module locally- api only ⇒ do not list the startup module; depend on core ⇒ must list it; adding view does not change the module code