Build → Build All Main Project Configurations。dist/ 目錄下將產生:
dist/
├── DefaultConfiguration/
│ ├── MarvTheMiner.jar
│ └── MarvTheMiner.jad
├── NokiaSeries60/
│ ├── MarvTheMiner.jar
│ └── MarvTheMiner.jad
├── NokiaOther/
│ ├── MarvTheMiner.jar
│ └── MarvTheMiner.jad
├── Motorola/
│ ├── MarvTheMiner.jar
│ └── MarvTheMiner.jad
└── Vodafone/
├── MarvTheMiner.jar
└── MarvTheMiner.jad
每個 JAR 僅含對應平台類,體積最小化。若缺少某平台庫導致預驗證失敗,手動註釋該配置的平台調用碼或補全庫。
Properties → Application Descriptor → 取消「Use Values from DefaultConfiguration」→ 設定專屬 MIDlet-Version、MIDlet-Name。
專案 A(庫)與專案 B(應用)均有 Release/Debug 配置:
Release 配置下選 A 的 dist/Release/ JARDebug 配置下選 A 的 dist/Debug/ JARDefaultConfiguration 視角儲存(預處理器註釋保留),避免切換配置產生無謂 diff。nbproject/project.properties。ant run # 使用當前活動配置
ant run -Dconfig.active=NokiaSeries60 # 指定配置
| 方案 | 操作 | 適用場景 |
|---|---|---|
| Libraries & Resources | 預製 res_large.jar、res_medium.jar、res_small.jar,各配置指向對應 JAR | 大量圖片/音效、解析度差異大 |
| Filtering | 資源置於 src/ 下,Filtering 樹勾選各配置包含的檔案 | 少量差異檔案、同名不同內容 |
路徑:{userhome}/.netbeans/{version}/config/Services/Platforms/org-netbeans-api-java-Platform/
檔名:SDK_4.1_MRI_7.5.xml
<?xml version='1.0'?>
<!DOCTYPE platform PUBLIC '-//NetBeans//DTD J2ME PlatformDefinition 1.0//EN'
'https://www.netbeans.org/dtds/J2ME-platformdefinition-1_0.dtd'>
<platform name="Motorola_7_5"
home="C:/WTK/MotorolaSDK v4.1 for J2ME/Emulator7.5"
type="custom"
displayname="Motorola 7.5"
srcpath=""
preverifycmd=""{platformhome}/bin/preverify.exe" -classpath "{classpath}" -d "{destdir}" "{srcdir}""
runcmd="">
<device name="Motorola_7_5" securitydomains="trusted,untrusted"
description="Motorola 7.5">
<configuration name="CLDC" version="1.1" displayname="CLDC"
classpath="${platform.home}/lib/cldc.zip" dependencies="" default="true"/>
<profile name="MIDP" version="2.0" displayname="MIDP"
classpath=";${platform.home}/lib/midp.zip" dependencies="" default="true"/>
</device>
</platform>
重啟 IDE,刪除 {userhome}/var/cache/(保留 mdrstorage),即可在 Platform Manager 見到 Motorola 7.5。
編輯專案 build.xml,新增目標:
<target name="run" depends="init">
<condition property="run.motorola">
<equals arg1="${config.active}" arg2="Motorola"/>
</condition>
<ant target="run_normal" unless="run.motorola"/>
<ant target="run_motorola" if="run.motorola"/>
</target>
<target name="run_normal" depends="init">
<nb-run commandline="${platform.runcommandline}" ... />
</target>
<target name="run_motorola" depends="init">
<property name="project.home" location="."/>
<java dir="${platform.home}/bin" fork="true"
classname="com.mot.tools.j2me.emulator.Emulator"
classpath="${platform.home}/bin/Emulator.jar;${platform.home}/bin/configtool.jar">
<jvmarg value="-Djava.library.path=${platform.home}/lib"/>
<arg value="-classpath ${project.home}/${dist.dir}/${dist.jar}"/>
<arg line="-deviceFile"/>
<arg value="${platform.home}/bin/RESOUR~1/T720I~1.PRO"/>
<arg line="javax.microedition.midlet.AppManager Miner -JSA 1 1"/>
</java>
</target>
原理:config.active=Motorola 時觸發 run_motorola,直接用 java 命令啟動模擬器主類,傳遞 JAR 路徑、裝置描述檔、MIDlet 類名。
| 維度 | 傳統做法 | NetBeans 方案 |
|---|---|---|
| 平台隔離 | 運行時 Class.forName + 註釋 | 編譯時預處理器區塊 + 專案配置 |
| JAR 體積 | 含所有平台碼 | 僅含目標平台碼 |
| 效能 | 運行時分派開銷 | 零開銷 |
| 原始碼可讀性 | 雜亂 | 清晰區塊標記 |
| 建置自動化 | 手動切換/打包 | Ant 一鍵多 JAR / CI 整合 |
| 非標準模擬器 | 無法整合 | XML 定義 + build.xml 自定義 run 目標 |
Marv The Miner 重構完成。同一碼庫,5 個配置,5 個精簡 JAR,零運行時平台判斷。這就是專業 J2ME 團隊的交付標準:**配置管理編譯時變異點,預處理器隔離平台差異,Ant 自動化多產物產出**。掌握這套流程,設備碎片化不再是噩夢,而是可控的工程變量。