J2ME Polish
J2ME Polish 2.4 Documentation
Enough Software

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/android" if="polish.android" />
	<source dir="source/midp" unless="polish.android" />
</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" />
	<library file="libraries/native.jar" if="polish.vendor==Nokia" convertImports="false" />
	<library file="libraries/native2-obfuscated.jar" if="polish.vendor==Nokia" obfuscate="false" />
	<library file="libraries/samsung-extension.jar" if="polish.vendor==Samsung" onDevice="true" />
</libraries>

With convertImports you can selectively stop the conversion of javax.microedition.lcdui classes to their J2ME Polish counterparts. This can be important for some libraries that in turn call native code of the target device. This is only relevant when you use the J2ME Polih Lush UI.

Use onDevice="true" for specifying a device library that is not included into the packaged application JAR, but that is available for compilation. Alternatively you can achieve the same result by specifying a device in custom-devices.xml and register the library in custom-apis.xml, but embedding this into the build.xml script is often easier.

Use obfuscate="false" to exclude a library from obfuscation. In this case it will be merged into the generated package after the obfuscation step.This setting also implicitely tells J2ME Polish not to convert the import statements (convertImports).

<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 &gt;= 240 and polish.ScreenHeight &gt;= 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 Ant's 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 <compilerarg> 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.

compilerarg Attributes  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" 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".
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" name="ProGuard" >
	<keep class="com.company.dynamic.SomeDynamicClass" />
	<keep class="com.company.dynamic.AnotherDynamicClass" />
	<parameter name="-verbose" value="true" />
</obfuscator>

The used MIDlet classes do not need to be set with the <keep> element, since they are saved from obfuscation automatically.

A similar approach is to use the #dontobfuscate preprocesing directive in the corresponding Java source file of the class.

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" 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.

You can use ProGuard by setting the name-attribute of the <obfuscator> element to "ProGuard".

<obfuscator unless="test" 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/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" 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/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" 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/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" 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 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 element contains a number of -sub-elements which define the actual attributes:

<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:
  • ${polish.jarPath}: the full path to the jar-file which should be created.
  • ${polish.packageDir}: the directory which contains the classes and the resources which should be "jared".
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>
back to top