The <build> Section
Control your build process with the <build> section!
The <build> section is the main configuration point of J2ME Polish.
<build
fullscreen="menu"
usePolishGui="true"
>
<!-- midlets definition -->
<midlet class="de.enough.polish.example.MenuMidlet" name="Example" />
<!-- project-wide variables - used for preprocessing -->
<variables>
<variable file="configs/all.properties" />
<variable file="configs/${polish.vendor}.properties" />
</variables>
<!-- obfuscator settings -->
<obfuscator name="ProGuard" unless="test or polish.blackberry" />
<!-- debug settings -->
<debug showLogOnError="true"
verbose="true"
level="error"
if="test"
>
<filter package="de.enough.polish.example" level="debug" />
<filter class="de.enough.polish.ui.Gauge" level="info" />
</debug>
</build>
Supported Attributes
The build section has... well... some options that you can use. Thankfully most of the settings are optional. For a good starting point have a look at the build.xml scripts of the sample applications.
| build Attribute | Required | Explanation |
|---|---|---|
| sourceDir | No | The path to the source directory. The default path is either "source/src", "source" or "src". You can define several paths by separating them with a colon ':' or a semicolon ';': [path1]:[path2]. You can also include source-directories based on conditions when the nested <sources> element is used instead. |
| binaryLibraries or binaryLibrary | No | Either the name of the directory which contains binary-only libraries or the name(s) of the libraries. Several libraries can be separated by colons ':' or by semicolons ';'. When no path is defined, the libraries will be searched within the "import" folder by default.
This mechanism can only be used for third party APIs, which are not available on the phone itself. Device-APIs are automatically included, after they have been defined in the ${j2mepolish.home}/apis.xml file. Please compare the how-to about including APIs.
Alternatively you can used a nested <libraries> element.
|
| symbols | No | Project specific preprocessing symbols, e.g. "showSplash" which can be checked with "//#ifdef showSplash" in the source code. Several symbols need to be separated by comma. |
| usePolishGui | No | Defines whether the J2ME Polish GUI should be used at all. Possible values are true, false and
always. When you set it to true
the GUI will be used only for devices which have the recommended capabilities (e.g. a color depth of at least 8 bits).
Use always for using the GUI for all devices. Default value is true.
Use the preprocessing variable polish.usePolishGui for a more finegrained control.
|
| fullscreen | No | Defines whether the complete screen should be used for devices which support
a full screen mode. Currently these include all MIDP 2.0 devices as well as devices,
which support the Nokia-UI API. Possible values are either "no", "yes" and "menu". With "yes" the complete screen is used but no commands are supported. With "menu" commands can be used as well. Default setting is "no". Remember that you need to target a specific device that has known Softkeys for this option. Otherwise always the default ("unpolishable") commands menu is used.
Alternatively the preprocessing-variable polish.FullScreen can be set. This allows a finer grained
control, since variables can have conditions, e.g.:
<build
usePolishGui="true"
fullscreen="menu"
>
<variables>
<variable
name="polish.FullScreen"
value="true"
if="polish.vendor == Siemens"
/>
<variables>
[...]
|
| javacTarget | No | The target for the java-compiler. By default the "1.2" target is used, unless a WTK 1.x is used, in which case the target "1.1" is used. |
| preverify | No | The path to the preverify executable of the Wireless Toolkit. The program is usually within the "bin" folder of the Wireless Toolkit. This can be used for defining a preverfying program different from the standard WTK program. |
| polishDir | No | The directory containing the sources of J2ME Polish. This is used by developers of the J2ME Polish GUI itself. |
| devices | No | Path to the devices.xml-file. Defaults to devices.xml in the current folder or in enough-j2mepolish-build.jar. |
| groups | No | Path to the groups.xml-file. Defaults to groups.xml in the current folder or in enough-j2mepolish-build.jar. |
| vendors | No | Path to the vendors.xml-file. Defaults to vendors.xml in the current folder or in enough-j2mepolish-build.jar. |
| apis | No | Path to the apis.xml-file. Defaults to apis.xml in the current folder or in enough-j2mepolish-build.jar. |
| midp1Path | No | Path to the MIDP/1.0 API. Defaults to "import/midp1.jar". |
| midp2Path | No | Path to the MIDP/2.0 API. Defaults to "import/midp2.jar" |
| workDir | No | The temporary build folder. Defaults to "build". |
| destDir | No | The folder into which the "ready-to-deploy" application bundles should be stored. Defaults to "dist". |
| apiDir | No | The folder in which the APIs are stored, defaults to "import". |
| resDir | No | The folder which contains all design definitions and other resources like images, movies etc. By setting a different folder, completely different designs can be demonstrated. Default folder is "resources". You can also use the <resources> subelement which allows to fine-tune the resource-assembling process as well. |
| obfuscate | No | Either true or false. Defines whether the applications should be obfuscated. Defaults to "false". Alternatively the nested element "obfuscator" can be used (see below). |
| obfuscator | No | The name of the obfuscator. Defaults to "ProGuard". Possible values are "ProGuard", "KlassMaster", "Dasho", "YGuard" or "RetroGuard". Alternatively the nested element "obfuscator" can be used (see below). |
| compilerMode | No | When the compiler-mode is activated, J2ME Polish will not package the application and only process one device. This mode is useful for IDEs which support indirect compilation like NetBeans for example. You can select "Run" in NetBeans and NetBeans uses J2ME Polish as compiler, packages the application and starts the emulator - this saves valuable time during the development phase. Possible values are true or false. The compiler mode is deactivated ("false") by default.
|
| compilerDestDir | No | The "compilerDestDir"-attribute defines where the compiled (and obfuscated) classes should be stored. The default target directory is "bin/classes". |
| compilerModePreverify | No | Defines whether J2ME Polish should preverify the compiled classes as well. This is needed for using J2ME Polish as a compiler for the EclipseME plugin. Possible values are true or false. The preverifying is deactivated ("false") by default.
|
| encoding | No | The encoding for the generated JAD and MANIFEST files, this defaults to "UTF8" like the standard mandates. |
Nested Elements
The build section supports very few nested elements that are described below in detail.
<sources>
The <sources> element can be used for a finer grained control of the source-directories. This can be useful to include test classes, for example:
<sources> <source dir="source/src" /> <source dir="source/test" if="test" /> </sources>
| sources Attribute | Required | Explanation |
|---|---|---|
| if | No | The Ant-property which needs to be true; for the nested source directories to be used. |
| unless | No | The Ant-property which needs to be false; for the nested source directories to be used. |
| source Attribute | Required | Explanation |
|---|---|---|
| dir | Yes | The directory containing Java source files. |
| if | No | The Ant-property or preprocessing term which needs to be true; for this source directory to be used. |
| unless | No | The Ant-property or preprocessing term which needs to be false; for this source directory to be used. |
<libraries>
Add compiled libraries to your project with the <libraries> element:
<libraries> <library file="libraries/tinyline.gz" /> <library file="libraries/svghelper.jar" if="polish.api.svg" /> </libraries>
<midlet> and <midlets>
The <midlet> element defines the actual MIDlet class:
<midlet class="de.enough.polish.example.ExampleMidlet" />
| midlet Attribute | Required | Explanation |
|---|---|---|
| class | Yes | The complete package and class-name of the MIDlet. |
| name | No | The name of the MIDlet. Default is the class-name without the package: The MIDlet "com.company.SomeMidlet" is named "SomeMidlet" by default. |
| icon | No | The icon of this MIDlet. When none is defined, the icon defined in the <info> section will be used. |
| number | No | The number of this MIDlet. This is interesting only for MIDlet-suites in which several MIDlets are contained. |
| if | No | The Ant-property or preprocessing directive which needs to be true; for this MIDlet to be used. |
| unless | No | The Ant-property or preprocessing directive which needs to be false; for this MIDlet to be used. |
The optional <midlets> element is used as a container for several <midlet> elements and also supports the if/unless attributes:
<midlets> <midlet class="de.enough.polish.example.ExampleMidlet" /> <midlet name="J2ME Polish Demo" number="2" icon="no2.png" class="de.enough.polish.example.GuiDemoMidlet" /> </midlets>
<iappli>
The <iappli> or <doja> element defines the IApplication class of your DoJa release. This is only applicable when you are targeting this platform.
| iappli Attribute | Required | Explanation |
|---|---|---|
| class | Yes | The complete package and class-name of the main IApplication. |
| if | No | The Ant-property or preprocessing directive that needs to be/result "true" for this iappli to be used. |
| unless | No | The Ant-property or preprocessing directive that needs to be/result "false" for this iappli to be used. |
<resources>
<resources
dir="resources"
excludes="*.txt"
>
<fileset
dir="resources/multimedia"
includes="*.mp3"
if="polish.audio.mp3"
/>
<fileset
dir="resources/multimedia"
includes="*.mid"
if="polish.audio.midi and not polish.audio.mp3"
/>
<fileset
dir="resources/multimedia/${polish.language}"
includes="*.mid"
/>
<localization locales="de, en" unless="test" />
<localization locales="en" if="test" />
</resources>
The <resources> element can be used to fine tune the resources assembling as well as the localization of the application. When it is used, the "resDir"-attribute of the <build> section should not be used. The <resources> element supports following attributes:
| resources Attribute | Required | Explanation |
|---|---|---|
| dir | No | The directory containing all resources, defaults to the "resources" folder. |
| defaultexcludes | No | Either true or false. Defines whether typical files should not be copied in the application-jar-bundle during packaging. The files "polish.css", "Thumbs.db", any backup-files (*.bak and *~) and the messages-files used in the localization are excluded by default. |
| excludes | No | Additional files which should not be included in the JAR-files can be defined using the "excludes"-attribute. Several files need to be separated by comma. The star can be used to select several files at once, e.g. "*.txt, readme*". |
| locales | No | The locales which should be supported in a comma-separated list. Alternatively the nested <localization> element can be used for finetuning the settings. The standard Java locale-abbreviations are used, e.g. "de" for German, "en" for English and "fr_CA" for Canadian French. |
| filterZeroLengthFiles | No | Defines whether files with a length of 0 should also be filtered. This is true by default, so
any files with a length of 0 bytes will not be copied, unless you activate this by setting
filterNullFiles="false". You can use this mechanism for removing
files for specific devices or device groups. Imagine the situation where you have a image
file in the "resources" directory. You want to use that image on all devices except
the Vendor/DeviceName one. You can now remove that file for that specific devices by placing
a file with the same name but with a length of 0 bytes into "resources/Vendor/DeviceName".
|
The <resources> elements accepts the nested elements <root>, <localization> <filter>, <fileset> and <copier>.
The <root> Subelement
By default you only have the single root directory resources in your project. You can, however, define as many
roots and even conditional roots using the <root> element:
<resources dir="resources/base" defaultexcludes="true" excludes="readme.txt" > <root dir="resources/base/design" /> <root dir="resources/base/sounds" /> <root dir="resources/base/images" /> <root dir="resources/base/images/largescreens" if="polish.ScreenWidth >= 240 and polish.ScreenHeight >= 300" /> <root dir="resources/base/images/i18n" includeSubDirs="true" includeBaseDir="true" excludes="CVS, readme*" /> </resources>
| root Attribute | Required | Explanation |
|---|---|---|
| dir | Yes | The base directory of this resource root. This directory needs to exist unless you use variables in it like ${polish.vendor}, ${polish.name}, ${polish.language}, ${polish.country} and so on. You can use any J2ME Polish preprocessing variable or Ant property in the dir attribute. |
| includeSubDirs | No | Set to true if you want to include all subdirectories instead of using the root directory as a starting point for the
normal resource assembling. This allows you to include resources with the same name in different folder, which can
be useful for dynamic localizations, for example:
resources/base/images/i18n/en/flag.png resources/base/images/i18n/de/flag.png resources/base/images/i18n/dk/flag.png resources/base/images/i18n/fr/flag.png resources/base/images/i18n/es/flag.png resources/base/images/i18n/cn/flag.png |
| includeBaseDir | No | Set to true if you want to include the directory specified in the dir attribute as well.
Is only applicable when you have set the includeSubDirs attribute to true.
|
| excludes | No | Comma separated list of files that should be excluded, e.g. excludes="CVS, readme*". |
| includes | No | Comma separated list of files that should be included, e.g. includes="*.mid". |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this root to be used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this root to be used. |
The <localization> Subelement
Control the internationalization of your application with the the <localization> element:
<localization dynamic="true" defaultLocale="en"> <locale name="en" encoding="UTF-8" /> <locale name="de" encoding="UTF-8" /> <locale name="cn" encoding="GB2312" /> </localization>
| localization Attribute | Required | Explanation |
|---|---|---|
| locales | No | The locales which should be supported in a comma-separated list - alternatively you can use nested <locale> elements. The standard Java locale-abbreviations are used, e.g. "de" for German, "en" for English and "fr_CA" for Canadian French. |
| messages | No | The file which contains the translations. This defaults to messages.txt. |
| dynamic | No | Defines whether dynamic translations should be enabled. Dynamic translations can be changed during runtime but require additional resources. This defaults to "false". |
| default | No | The default localization - this makes only sense when dynamic translations are enabled. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this localization to be used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this localization to be used. |
Use Locale Dependent Encodings with <locale>
Use nested <locale> elements for configuring settings for each locale that you support:
<locale name="cn" encoding="GB2312" if="polish.vendor == Motorola" />
| locale Attribute | Required | Explanation |
|---|---|---|
| name, names | Yes | The name of the locale e.g. "de" for German, "en" for English and "fr_CA" for Canadian French. You can specify several locales by separating them with commas:
names="de, en".
|
| encoding | No | The encoding of the corresponding messages_${locale}.txt file. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this locale to be used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this locale to be used. |
The <filter> Subelement
Sometimes it is easier to exclude resources for specific devices rather than to include it for the other devices. You can use any number of <filter> elements for this purpose. The following element removes all *.mid files when the target device supports both MIDI as well as AMR files:
<filter excludes="*.mid" if="polish.audio.midi and polish.audio.amr" />
| filter Attribute | Required | Explanation |
|---|---|---|
| excludes | Yes | Defines which files should be excluded, e.g. "*.mid". You can also use regular expressions in this attribute. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this filter to be used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this filter to be used. |
The <fileset> Subelement
You can use <fileset> for fine tuning the resource assembling. Nowadays we recommend using
<root> instead.
The <fileset> behaves like any Ant fileset, but it offers the additional "if" and "unless"-attributes for allowing a fine grained control. The most important attributes are:
<resources dir="resources" excludes="readme*" > <fileset dir="resources/multimedia" includes="*.mp3" if="polish.audio.mp3" /> <fileset dir="resources/multimedia" includes="*.mid" if="polish.audio.midi and not polish.audio.mp3" /> </resources>
In the above example MIDI files are only included when two conditions are met:
1) The device supports MIDI sound
2) The device does not support MP3 sound.
| fileset Attribute | Required | Explanation |
|---|---|---|
| dir | Yes | The base directory of this fileset. This directory needs to exist unless you use variables in it like ${polish.vendor}, ${polish.name}, ${polish.language}, ${polish.country} and so on. You can use any J2ME Polish preprocessing variable or Ant property in the dir attribute. |
| includes | Yes | Defines which files should be included, e.g. "*.mid". |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this fileset to be included. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this fileset to be included. |
The <copier> Subelement
Use the <copier> element to transform the resources before they are packaged in the final JAR file. You can chain several copiers together just by defining several <copier> elements.
| copier Attribute | Required | Explanation |
|---|---|---|
| name | Yes, unless class is set | The name of the resource copier, e.g. "antcall", "renamer" or "svgconverter". You can register your own resource copier in ${polish.home}/custom-extensions with the type "resourcecopier". |
| class | No | The class that extends the de.enough.polish.resources.ResourceCopier class. |
| classpath | No | The classpath that is used. |
| target | No | The target in your build.xml script that should be called when using the "antcall" copier. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this copier to be used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this copier to be used. |
The antcall Resource Copier
The "antcall" resource copier executes another target in your build.xml script for copying the resources. You can use all (lowercase) J2ME Polish variables and properties of the current target device as well as following specific properties:
- ${polish.resources.target}: contains the target directory, to which the resources need to be copied
- ${polish.resources.files}: includes a comma separated list of the files that should be copied
- ${polish.resources.filePaths}: includes a semicolon (Windows) or colon (Unix) separated list of the files that should be copied.
You can also specify your own properties by using nested <parameter> elements.
<copier name="antcall" target="copyresources">
<parameter name="MySettings" value="${polish.name}.settings" />
</copier>
The renamer Resource Copier
Use the "renamer" resource copier for modifying the file-names of the resources before they are packaged in the final JAR. The following renamer removes all characters that are surrounded by curly braces. You can use this for giving your resources meaningful names while using short names in the JAR file. The file i0{ start game icon }.png will be renamed to i0.png, for example. This saves some precious space.
<copier name="renamer">
<!-- use a regular expression for defining
name parts that should be changed:
-->
<parameter name="searchPattern" value="\{.*\}" />
<!-- define the replacement for the searchPattern here: -->
<parameter name="replacement" value="" />
</copier>
The svgconverter Resource Copier
Use the "svgconverter" for modifying SVG images of the resources before they are packaged in the final JAR. The svgconverter allows you to provide only one icon or background image for a variety of phones. It scales the SVG image to the appropriate size of the current target device and converts it into a PNG image. For an background image you have to start naming your image "bg"("bg"+whatever+".svg"), for an icon start with "icon". The svgconverter then uses the defined ScreenSize and IconSize of the target device for scaling such images. When the target device does not specify these sizes the default size for icons is 15x15 and for backgrounds 128x160 pixels.
<copier name="svgconverter" />
<compiler>
The optional <compiler> element can be used for specifying any compiler-arguments. J2ME Polish normally calls the Java compiler normally with the appropriate classpath as well as bootclasspath for the current target device. In some cases you might want to adjust the compiler settings, however, so you can use the nested <compiler> element. Along to all attributes of the standard <javac> task, the <compiler> element also supports the "if" and "unless" attributes for selecting to appropriate compiler setting:
| localization Attribute | Required | Explanation |
|---|---|---|
| srcdir | No | Location of the java files, which defaults to the temporary directory to which the preprocessed files are written. |
| destdir | No | Location to store the class files. This defaults to the temporary build directory into which class files are written before they are obfuscated. |
| includes | No | Comma- or space-separated list of files (may be specified using wildcard patterns) that must be included; all .java files are included when omitted. |
| includesfile | No | The name of a file that contains a list of files to include (may be specified using wildcard patterns). |
| excludes | No | Comma- or space-separated list of files (may be specified using wildcard patterns) that must be excluded; no files (except default excludes) are excluded when omitted. |
| excludesfile | No | The name of a file that contains a list of files to exclude (may be specified using wildcard patterns). |
| classpath | No | The classpath to use. J2ME Polish includes all supported libraries of the current target device by default. |
| classpathref | No | The classpath to use, given as a reference to a path defined elsewhere. |
| sourcepath | No | The sourcepath to use; defaults to the value of the srcdir attribute. To suppress the sourcepath switch, use sourcepath="". |
| sourcepathref | No | The sourcepath to use, given as a reference to a path defined elsewhere. |
| bootclasspath | No | Location of bootstrap class files. J2ME Polish uses either the platform specific library files for the bootclasspath, e.g. midp1.jar or midp2-cldc11.jar. |
| bootclasspathref | No | Location of bootstrap class files, given as a reference to a path defined elsewhere. |
| extdirs | No | Location of installed extensions. |
| encoding | No | Encoding of source files. (Note: gcj doesn't support this option yet.) |
| nowarn | No | Indicates whether the -nowarn switch should be passed to the compiler; defaults to off. |
| debug | No | Indicates whether source should be compiled with debug information; defaults to off. If set to off, -g:none will be passed on the command line for compilers that support it (for other compilers, no command line argument will be used). If set to true, the value of the debuglevel attribute determines the command line argument. J2ME Polish only enables the debugging when the <debug> element is active for the current target device. |
| debuglevel | No | Keyword list to be appended to the -g command-line switch. This will be ignored by all implementations except modern and classic(ver >= 1.2). Legal values are none or a comma-separated list of the following keywords: lines, vars, and source. If debuglevel is not specified, by default, nothing will be appended to -g. If debug is not turned on, this attribute will be ignored. |
| optimize | No | Indicates whether source should be compiled with optimization; defaults to off. |
| deprecation | No | Indicates whether source should be compiled with deprecation information; defaults to off. |
| target | No | Generate class files for specific VM version (e.g., 1.1 or 1.2). J2ME Polish uses 1.2 by default when the WTK 2.x is used. The target can also be set with the "javacTarget"-attribute of the <build> element. |
| verbose | No | Asks the compiler for verbose output; defaults to no. |
| depend | No | Enables dependency-tracking for compilers that support this (jikes and classic). |
| includeAntRuntime | No | Whether to include the Ant run-time libraries in the classpath; defaults to false. |
| includeJavaRuntime | No | Whether to include the default run-time libraries from the executing VM in the classpath; defaults to no. |
| fork | No | Whether to execute javac using the JDK compiler externally; defaults to no. |
| executable | No | Complete path to the javac executable to use in case of fork="yes". Defaults to the compiler of the Java version that is currently running Ant. Ignored if fork="no". Since Ant 1.6 this attribute can also be used to specify the path to the executable when using jikes, jvc, gcj or sj. |
| memoryInitialSize | No | The initial size of the memory for the underlying VM, if javac is run externally; ignored otherwise. Defaults to the standard VM memory setting. (Examples: 83886080, 81920k, or 80m) |
| memoryMaximumSize | No | The maximum size of the memory for the underlying VM, if javac is run externally; ignored otherwise. Defaults to the standard VM memory setting. (Examples: 83886080, 81920k, or 80m) |
| failonerror | No | Indicates whether the build will continue even if there are compilation errors; defaults to true. |
| source | No | Value of the -source command-line switch; will be ignored by all implementations prior to javac1.4 (or modern when Ant is not running in a 1.3 VM) and jikes. If you use this attribute together with jikes, you must make sure that your version of jikes supports the -source switch. Legal values are 1.3, 1.4 and 1.5 - by default, the "1.3" source switch will be used. |
| compiler | No | The compiler implementation to use. If this attribute is not set, the value of the build.compiler property, if set, will be used. Otherwise, the default compiler for the current VM will be used. |
| listfiles | No | Indicates whether the source files to be compiled will be listed; defaults to no. |
| tempdir | No | Where Ant should place temporary files. This is only used if the task is forked and the command line args length exceeds 4k. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this compiler-setting to be used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this compiler-setting to be used. |
The <compilerargs> Subelement
You can specify additional command line arguments for the compiler with nested <compilerarg> elements. These elements are specified like Command-line Arguments but have an additional attribute that can be used to enable arguments only if a given compiler implementation will be used.
| compilerargs Attribute | Required | Explanation |
|---|---|---|
| value | Either value, line, file or path | A single command-line argument; can contain space characters. |
| line | Either value, line, file or path | A single command-line argument; cannot contain space characters. |
| file | Either value, line, file or path | The name of a file as a single command-line argument; will be replaced with the absolute filename of the file. |
| path | Either value, line, file or path | A string that will be treated as a path-like string as a single command-line argument; you can use ; or : as path separators and Ant will convert it to the platform's local conventions. |
| compiler | No | Only pass the specified argument if the chosen compiler implementation matches the value of this attribute. |
<postcompiler>
Use a <postcompiler> for adjusting the class files after they have been compiled.
Prime example of the power of postcompiling are the Java 5 Syntax Support and the Floater Tool, which allows you to use floating point calculations on CLDC 1.0 devices.
<postcompiler name="java5" />
You can also call an Ant target in your build.xml script for post-processing class files:
<postcompiler name="antcall" target="AntPostcompileTarget" />
Next to all device capabilities you can access the polish.postcompile.dir Ant property
in your target.
<obfuscator>
The optional <obfuscator> element controls the obfuscating of the application bundle, which decreases the jar-size and makes it difficult to reverse engineer the application.
<obfuscator name="ProGuard" useDefaultPackage="true" unless="test" />
| obfuscator Attribute | Required | Explanation |
|---|---|---|
| name | No | The name of the obfuscator which should be used. Defaults to "ProGuard". Possible values are at the moment either "ProGuard", "KlassMaster" "Dasho", "YGuard" or "RetroGuard". |
| useDefaultPackage | No | J2ME Polish can move all classes to the default package for you. This includes the MIDlet-classes as well and can result in a smaller jar-size. Please note that you are responsible for preventing name-clashes of classes. You do not need to adjust your <midlet> settings, this is done automatically by J2ME Polish. This defaults to "false". |
| if | No | The name of the Ant-property which needs to be true; or "yes" to use this <obfuscator>. |
| unless | No | The name of the Ant-property which needs to be false; or "no" to use this <obfuscator>. |
| class | No | The class which controls the obfuscator. Each class which extends de.enough.polish.obfuscate.Obfuscator can be used. With this mechanism third
party obfuscators can be integrated easily. |
| classPath | No | The classpath for this obfuscator. This is useful for integrating a third party obfuscator. |
Any number of <obfuscator> elements can be used in a project. All active obfuscators are combined by J2ME Polish.
The <obfuscator> supports the subelements <keep> and <parameter>.
The <keep> Subelement
The <keep> element is used to define classes which are loaded dynamically (e.g. with Class.forName(...) ) and should not be obfuscated:
<obfuscator unless="test" enable="true" name="ProGuard" > <keep class="com.company.dynamic.SomeDynamicClass" /> <keep class="com.company.dynamic.AnotherDynamicClass" /> </obfuscator>
The used MIDlet classes do not need to be set with the <keep> element, since they are saved from obfuscation automatically.
The <parameter> Subelement
The <parameter> element is used to specify parameters for the obfuscator. This can be useful for integrating third party obfuscators which require additional settings:
<obfuscator unless="test" enable="true" name="ProGuard" > <keep class="com.company.dynamic.SomeDynamicClass" /> <keep class="com.company.dynamic.AnotherDynamicClass" /> <parameter name="scriptFile" value="../scripts/obfuscate.script" /> </obfuscator>
Combining Several Obfuscators
Several obfuscators can be combined just by specifying several <obfuscator> elements. When the <keep> subelement is used, it only needs to be specified on of the <obfuscator> elements. J2ME Polish will then use the obfuscated output of one obfuscator as input for the following obfuscator.
Specific Obfuscator Settings
ProGuard
ProGuard is an excellent obfuscator, shrinker and optimizer by Eric Lafortune. It is freely availabe under the GNU General Public License and can be downloaded from http://proguard.sourceforge.net.
If you want to use ProGuard as an obfuscator, please make sure that the proguard.jar-file is listed in the classpath of the J2ME Polish task-definition (build.xml):
<taskdef name="j2mepolish"
classname="de.enough.polish.ant.PolishTask"
classpath="${polish.home}/import/enough-j2mepolish-build.jar:
${polish.home}/import/jdom.jar:
${polish.home}/import/proguard.jar"/>
You can use ProGuard by setting the name-attribute of the <obfuscator> element to "ProGuard".
ProGuard 3.x offers an additional optimization of the bytecode, which is disabled by default. The optimization can be enabled by setting the "optimize"-parameter to "true":
<obfuscator unless="test" enable="true" name="ProGuard" > <parameter name="optimize" value="true" /> </obfuscator>
A text-file which lists all renaming operations is written to build/[vendor]/[device]/[locale]/obfuscation-map.txt. This file is useful if you get exceptions in the obfuscated application.
yGuard
The yGuard obfuscator by the yWorks GmbH is another interesting obfuscator and code-shrinker. J2ME Polish includes the library-classes, which are licensed under the GNU Lesser General Public License. The full obfuscator is freely available from http://www.yworks.de.
If you want to use yGuard as an obfuscator, please make sure that either the yguard-lib.jar or the original yguard.jar is listed in the classpath of the J2ME Polish task-definition (build.xml):
<taskdef name="j2mepolish"
classname="de.enough.polish.ant.PolishTask"
classpath="${polish.home}/import/enough-j2mepolish-build.jar:
${polish.home}/import/jdom.jar:
${polish.home}/import/yguard-lib.jar"/>
The yGuard obfuscator can be used by setting the name-attribute of the <obfuscator> element to "YGuard":
<obfuscator unless="test" enable="true" name="YGuard" />
RetroGuard
RetroGuard is the basis of both yGuard and ProGuard and was developed by Retrologic Systems/Mark Welsh. It is licensed under the GNU Lesser General Public License and is included in J2ME Polish by default. It can be downloaded from http://www.retrologic.com.
You can use RetroGuard just by setting the "name"-attribute to "RetroGuard":
<obfuscator unless="test" enable="true" name="RetroGuard" />
Zelix KlassMaster
KlassMaster is a commercial obfuscator available from Zelix Pty Ltd. A free evaluation version can be requested at http://www.zelix.com.
The KlassMaster integration is based on the WTK-mechanism for calling obfuscators, therefore both the ZKM.jar as well as the kenv.zip needs to be on the classpath:
<taskdef name="j2mepolish"
classname="de.enough.polish.ant.PolishTask"
classpath="${polish.home}/import/enough-j2mepolish-build.jar:
${polish.home}/import/jdom.jar:
${polish.home}/import/ZKM.jar:${wtk.home}/wtklib/kenv.zip"/>
The KlassMaster-integration allows several parameters to be set:
enableFlowObfuscation: the flow-obfuscation increases the security of the application, but the application-size as well. It is deactivated by default, therefore. It can be activated by setting the enableFlowObfuscation-parameter to "true".ObfuscateFlowLevel: The obfuscation-flow level can also be set directly, e.g. "none" or "aggressive". This parameter takes precedent above the enableFlowObfuscation-parameter.ScriptFile: The file containing the full script can also be set. In that case please note that the source-jar-file is always the "build/source.jar" and the target-file is the "build/dest.jar".
The following example shows a possible invocation of KlassMaster:
<obfuscator unless="test" enable="true" name="KlassMaster" > <parameter name="ObfuscateFlowLevel" value="none" /> </obfuscator>
DashO Pro
DashO Pro is a commercial obfuscator by Preemptive Solutions. A free evaluation version can be requested at http://www.preemptive.com.
When the DashO Pro obfuscator is used, either the Ant property "dasho.home" or the parameter "DashoHome" needs to be given. The classpath does not need to be modified.
The DashO Pro obfuscator supports following parameters:
DashoHome: needs to point to the installation directory of the DashO Pro obfuscator.Version: needs to correspond to the used version of DashO. The current default version is "3.1".enableFlowObfuscation: when "true" is given, DashO will obfuscate the application flow as well. This is deactivated by default.enableStringEncription: when "true" is given, Strings will be obfuscated by DashO as well. Since this decreases the performance, it is deactivated by default.enableRenaming: when "true" is given, all possible classes will be renamed. This is activated by default.enableOptimization: when "true" is given, the byte-code will be optimized by DashO. This feature is activated by default.ConstantPoolTag: a tag which will be added to all processed classes. This is only visible when a decompiler is used.ScriptFile: The file containing the full script can also be set. In that case please note that the source-jar-file is always the "build/source.jar" and the target-file is the "build/dest.jar".
A report about the renamed clases as well as methods will be written to build/[vendor]/[device]/[locale]/obfuscation-map.txt. This file is useful for resolving stacktraces in the obfuscated application.
This example shows the integration of DashO Pro:
<obfuscator unless="test" enable="true" name="Dasho" > <parameter name="DashoHome" value="/home/user/DashOPro_3.1" /> <parameter name="Version" value="3.1" /> </obfuscator>
JODE
JODE is quite a powerful optimizer, shrinker and obfuscator by Jochen Hoenicke. It is licensed under the GNU General Public License and is available at http://jode.sourceforge.net free of charge.
If you want to use JODE, please make sure that the jode-jar-file is on the classpath:
<taskdef name="j2mepolish"
classname="de.enough.polish.ant.PolishTask"
classpath="${polish.home}/import/enough-j2mepolish-build.jar:
${polish.home}/import/jdom.jar:
${polish.home}/import/Jode-1.1.2-pre1.jar"/>
JODE supports the "ScriptFile"-parameter which can be used to specify the obfuscator-script. Please note that the source-jar-file is always the "build/source.jar" and the target-file is the "build/dest.jar":
<obfuscator unless="test" enable="true" name="Jode" > <parameter name="ScriptFile" value="obfuscate.jos" /> </obfuscator>
When no script-file-parameter is present, J2ME Polish will create a default script. Depending on the application and environment, several problems ranging from preverification/linking-errors to NullPointerExceptions in the JODE-API can occur. Maybe someone with more experience with JODE can provide help here - please get in touch with j2mepolish@enough.de.
<variables>
The optional <variables> element contains several variable definitions, which can be used for the preprocessing. This mechanism can be used for example to define configuration values:
<variables includeAntProperties="true"> <variable name="update-url" value="http://www.enough.de/update" /> <variable name="polish.TiledLayer.splitImage" value="true" if="polish.Vendor == Nokia" /> </variables>
| variables Attribute | Required | Explanation |
|---|---|---|
| includeAntProperties | No | Either true or false. When "true" all Ant-properties will be included and can be used in the preprocessing. Defaults to "false". |
The <variables> element contains an arbitrary number of <variable> elements, which define the actual variables. Each variable needs the attributes name and value:
| variable Attribute | Required | Explanation |
|---|---|---|
| name | Yes unless file is used | The name of the variable. |
| value | Yes unless file is used | The value of the variable. |
| file | No | The file which contains several variable-definitions. In the file the variable-names and -values are separated by equals-signs (=). Empty lines and lines starting with a hash-mark (#) are ignored. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this variable to be included. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this variable to be included. |
Variables which have been defined in this way can be included into the source code with the
"//#=" preprocessing directive and can be checked with the "[variable-name]:defined" symbol:
//#ifdef update-url:defined
//#= String url = "${ update-url }";
//#else
String url = "http://www.default.com/update";
//#endif
Variables can also be compared, please refer to the description of the #if-directive for more information.
<debug>
The optional <debug> element controls the inclusion of debugging messages for specific classes or packages. The debugging messages will be activated or deactivated in the source code, so the performance will not be decreased, when the debugging is deactivated.
<debug showLogOnError="true" verbose="false" level="error" if="test" > <filter pattern="com.company.package.*" level="info" /> <filter pattern="com.company.package.MyClass" level="debug" /> </debug>
In the source code any debug messages must be accompanied by a //#debug-directive:
//#debug
System.out.println("initialization done.");
or
//#debug warn
System.out.println("could not load something...");
or
//#debug error
System.out.println("could not load something: " + e);
You will find more information about the debugging possibilities in the introduction as well as in the preprocessing documentation.
| debug Attribute | Required | Explanation |
|---|---|---|
| level | No | The general debug level which is needed for debug messages. Possible values are "debug", "info", "warn", "error", "fatal" or a user-defined level. Default level is "debug", so all debugging messages will be included. |
| verbose | No | Either true or false. When "true" the time, class-name and line-number will be included in each debugging message. Defaults to "false".
When the verbose mode is enabled, the preprocessing symbol "polish.debugVerbose" will be defined.
In the verbose mode exceptions thrown by J2ME Polish will contain useful information. Also the key-handling and animation-handling will be monitored and error messages will be given out. |
| showLogOnError | No | Either true or false. When "true"
the log containing all logging-messages will be shown when an exception is logged.
An exception is logged by printing out a message which is followed by a plus and the exception variable:
//#debug error
System.out.println("could not load something: " + e);
Alternatively the Debug-class of J2ME Polish can be used directly. Then the log will be shown when the
Debug.debug( String message, Throwable exception ) method is called.
The log can only be shown automatically, when the J2ME Polish GUI is used. |
| if | No | The name of the Ant-property which needs to be true to use this <debug>.
When the <debug> element is activated, the preprocessing symbol "polish.debugEnabled" will be defined.
|
| unless | No | The name of the Ant-property which needs to be false; or "no" to use this <debug>. |
For a finer control of the debugging process, the <debug> element allows the sub-element <filter>, which defines the debug-level for specific classes or packages.
| filter Attribute | Required | Explanation |
|---|---|---|
| pattern | Yes | The name of the class or of the package. When the pattern ends with a star, all classes of that package will be included, e.g. "com.company.mypackage.*" |
| level | Yes | The debugging level for all classes with the specified pattern. Possible values are "debug", "info", "warn", "error", "fatal" or a user-defined level. |
<jad>
With the <jad> element user-defined attributes can be added to the JAD-file (Java Application Descriptor) as well as the MANIFEST-file which is contained in the created JAR-file. The
<jad> <attribute name="Nokia-MIDlet-Category" value="Game" if="polish.group.Series40" /> <attribute name="MIDlet-Push-1" value="socket://:79, com.sun.example.SampleChat, *" if="polish.midp2" /> </jad>
| attribute Attribute | Required | Explanation |
|---|---|---|
| name | Yes unless file is used | The name of the attribute, e.g. "Nokia-MIDlet-Category" |
| value | Yes unless file is used | The value of the attribute. |
| file | No | The file which contains several attribute-definitions. In the file the attribute-names and -values are separated by colons (:). Empty lines and lines starting with a hash-mark (#) are ignored. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true for this variable to be included. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false for this variable to be included. |
Attributes which are defined in this way can be loaded in the application with the MIDlet.getAppProperty( String name ) method, which needs the name of the attribute as an argument and returns the value of that argument. Often it is advisable to use the variable-mechanism of J2ME Polish instead, since such values are actually hard-coded into the application and are, therefore, much faster than the getAppProperty(...)-mechanism.
Sorting and Filtering JAD attributes
The JAD-attributes can filtered and sorted using the <jadFilter> subelement:
<jad> <attribute name="Nokia-MIDlet-Category" value="Game" if="polish.group.Series40" /> <jadFilter> MIDlet-Name, MIDlet-Version, MIDlet-Vendor, MIDlet-Jar-URL, MIDlet-Jar-Size, MIDlet-Description?, MIDlet-Icon?, MIDlet-Info-URL?, MIDlet-Data-Size?, MIDlet-*, * </filter> </jad>
The <jadfilter> element contains all allowed attribute names in the desired order and separated by commas. You can use different filters by using the "if" or "unless" attributes:
| jadFilter Attribute | Required | Explanation |
|---|---|---|
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true so that this filter is used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false so that this filter is used. |
Inside of the <jadfilter> element you can specify all allowed JAD-attributes in the desired order and separated by commas. Following syntax is used:
| jadFilter-Text | Example | Explanation |
|---|---|---|
| name | MIDlet-Name |
The complete name of a required attribute. |
| name followed by a questionmark | MIDlet-Icon? |
The complete name of an optional attribute. |
| beginning of a name followed by a star | MIDlet-* |
All remaining attributes which names start with the given sequence will be included at this position. |
| start | * |
All remaining attributes will be included at this position. A star can only positioned at the end of a filter. |
An overview about allowed attributes can be found at the appendix of the Pro J2ME Polish book.
<manifestFilter>
The manifest filter element can be used to sort and filter manifest attributes. Please note that the first included attribute should always be the "Manifest-Version"-attribute. Otherwise the application will most likely not work:
<manifestFilter> Manifest-Version, MIDlet-Name, MIDlet-Version, MIDlet-Vendor, MIDlet-1, MIDlet-2?, MIDlet-3?, MIDlet-4?, MIDlet-5?, MicroEdition-Profile, MicroEdition-Configuration, MIDlet-Description?, MIDlet-Icon?, MIDlet-Info-URL?, MIDlet-Data-Size? </manifestFilter>
The <manifestFilter> element contains all allowed attribute names in the desired order and separated by commas. You can use different filters by using the "if" or "unless" attributes:
| manifestFilter Attribute | Required | Explanation |
|---|---|---|
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true so that this filter is used. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false so that this filter is used. |
Inside of the <manifestFilter > element you can specify all allowed MANIFEST-attributes in the desired order and separated by commas. Following syntax is used:
| manifestFilter-Text | Example | Explanation |
|---|---|---|
| name | MIDlet-Name |
The complete name of a required attribute. |
| name followed by a questionmark | MIDlet-2? |
The complete name of an optional attribute. |
| beginning of a name followed by a star | MIDlet-* |
All remaining attributes which names start with the given sequence will be included at this position. |
| start | * |
All remaining attributes will be included at this position. A star can only positioned at the end of a filter. |
An overview about allowed attributes can be found at the appendix of the Pro J2ME Polish book.
<preprocessor>
The <preprocessor> element can be used to integrate own or third party preprocessors. This can be used for allowing new preprocessing directives for example.
<preprocessor class="com.company.preprocess.MyPreprocessor" classPath="import/preprocessing.jar" > <parameter name="scriptFile" value="../scripts/preprocess.script" /> </preprocessor>
| preprocessor Attribute | Required | Explanation |
|---|---|---|
| class | Yes | The class of the preprocessor. |
| classPath | Yes | The classpath for the preprocessor. |
| if | No | The name of the Ant-property, which needs to be true; or "yes", when this <preprocessor> element should be used. |
| unless | No | The name of the Ant-property, which needs to be false; or "no", when this <preprocessor > element should be used.. |
The preprocessor can be configured using a number <parameter> subelements. Each <parameter> subelement needs to define the attributes "name" and "value".
<packager>
Usually the efficient internal J2ME Polish packager is used for creating the final application bundles. For using a different packaging-program, the <packager> element can be used:
<packager
executable="jar"
arguments="cvfM;;${polish.jarPath};;-C;;${polish.packageDir};;."
/>
A much simpler but equally valid call is this:
<packager name="jar" />
A possible alternative might be the Open Source tool "7-Zip", which can create smaller files compared to the standard ZIP mechanism. This might result in problems on the actual device, though, so use with care. The 7-Zip tool can be obtained free of charge at http://www.7-zip.org.
The <packager> element supports following attributes:
| packager Attribute | Required | Explanation |
|---|---|---|
| name | Yes, unless executable or class is defined | The name of the packager, e.g. "jar", "antcall", "7zip" or "kzip". You can register your own packager in ${polish.home}/custom-extensions.xml by using the "packager" type. |
| target | No | The Ant target that should be used for the packaging step. Only relevant when the "antcall" packager is used. |
| executable | No | The name of the program, e.g. "jar" or "7za.exe". |
| arguments | Yes, unless class is used | The arguments for the packager. Several arguments can be separated by using double-semicolons (;;). Any Ant-properties as well as J2ME Polish variables can be used. Often needed variables are:
|
| class | No | The name of the class which extends the de.enough.polish.jar.Packager-class. This mechanism can be used for extending the packaging capabilities of J2ME Polish. In that case further parameters can be set using nested <parameter> elements. |
<sign>
The <sign> element signs your application for all MIDP 2.0 devices. Please note that you need a valid certificate for example from Verisign or Thawte. Some devices do not contain "open" certificates. In that case you either need to manually install a root certificate (only possible on some devices), use the java verified program or cooperate with a device vendor or an operator.
In the following example we are using the password ant property for specifying the password. In this way it can be specified on the command line
without risking the security:
ant -Dpassword=secret
<sign
key="SignMIDlet"
keystore="midlets.ks"
password="${password}"
unless="test"
/>
| sign Attribute | Required | Explanation |
|---|---|---|
| key | Yes | The name of the key used for signing. |
| keystore | Yes | The path of the keystore that contains the key. The path is taken relative to the build.xml script. |
| password | Yes | The passphrase used to protect the key. |
| if | No | The name of the Ant-property, which needs to be true; or "yes", when this <sign> element should be used. |
| unless | No | The name of the Ant-property, which needs to be false; or "no", when this <sign > element should be used.. |
<java>
The <java> element can be used to extend J2ME Polish with any Java utility. It accepts all attributes and nested elements like the Ant-<java> element (compare http://ant.apache.org/manual/CoreTasks/java.html) as well as the additional attribute "if", "unless" and "message". J2ME Polish variables can be used in the nested <arg> elements, so that the call can be adjusted for the current device.
Each defined <java> element is called after the successful creation of an application-bundle. A possible use of the <java> element is the signing of MIDlets, which is described in the signing-how-to.
The following example calls the JadUtil.jar of the Wireless Toolkit for signing a JAD file:
<java jar="${wtk.home}/bin/JadTool.jar"
fork="true"
failonerror="true"
if="polish.midp2"
unless="test"
message="Adding signature for device ${polish.identifier}"
>
<arg line="-addjarsig"/>
<arg line="-keypass ${password}"/>
<arg line="-alias SignMIDlet"/>
<arg line="-keystore midlets.ks"/>
<arg line="-inputjad dist/${polish.jadName}"/>
<arg line="-outputjad dist/${polish.jadName}"/>
<arg line="-jarfile dist/${polish.jarName}"/>
</java>
Following variables can be used in the <arg> element and the "message"-attribute:
- polish.vendor: The vendor of the current device, e.g. "Siemens" or "Nokia".
- polish.name: The name of the current device, e.g. "N-Gage".
- polish.identifier: The identifier of the current device, e.g. "Siemens/SX1".
- polish.version: The version of the application as defined in the info-section.
- polish.jarName: The name of the jar-file as defined in the info-section.
- polish.jadName: The name of the jad-file as defined in the info-section.
The most important attributes of the <java> element are:
| java Attribute | Required | Explanation |
|---|---|---|
| classname | either classname or jar | The name of the class which should be executed. |
| jar | either classname or jar | The location of the jar file to execute (must have a Main-Class entry in the manifest). Fork must be set to true if this option is selected. |
| fork | No | If enabled triggers the class execution in another VM (disabled by default). |
| message | No | A message which will be printed out on the standard output when this <java> element is executed. The message can contain J2ME Polish variables, such as ${ polish.identifier }. |
| if | No | The Ant-property which needs to be true; or the preprocessing term which needs result true when this <java> element should be executed. |
| unless | No | The Ant-property which needs to be false; or the preprocessing term which needs result false when this <java> element should be executed. |
The most important nested element is the <arg> element:
| arg Attribute | Required | Explanation |
|---|---|---|
| line | No | A space-delimited list of command-line arguments. |
Please refer to the Ant-documentation at http://ant.apache.org/manual/CoreTasks/java.html for more information about the <java> element.
<finalizer>
After J2ME Polish has finished compiling and packaging your application it can use a finalizer to do
some marvelous stuff. This is used for converting a JAR into a COD archieve for BlackBerry devices, for example.
An easy way to implement your own functionality is to use the antcall finalizer:
<finalizer name="antcall" target="MyFinalizerAntTarget" />
Next to all capabilities of the current target device you can then access the Ant properties polish.finalize.jar
and polish.finalize.jad in your MyFinalizerAntTarget:
<target name="MyFinalizerTarget">
<echo message="J2ME Polish is now finished with creating ${polish.finalize.jar} and ${polish.finalize.jad} for device ${polish.identifer}" />
</target>