mikroblogi/posts/2026-08-25-j2me-in-2026.html
2026-08-25 23:54:28 +03:00

121 lines
7.1 KiB
HTML

title: J2ME in 2026
date: 2026-08-25 20:54
---
<p>Basically all tutorials on J2ME I can find are
<ol>
<li>ancient</li>
<li>assuming you're using some kind of IDE</li>
<li>working off of Sun's WTK</li>
<li>some combination of the above</li>
</ol>
This is not great.</p>
<p>I have, fortunately however, managed to piece together enough
information to be able to do so.
I'll walk through building <a
href="https://felix.plesoianu.ro/mobile/pocket-gopher/">a simple J2ME
app</a>, using only free software that's still maintained (well,
mostly) so that this is documented somewhere.</p>
<p>For tooling, we'll be using
<dl>
<dt>OpenJDK 8</dt>
<dd>Still maintained for the time being. It's the last version of
OpenJDK that supports code generation for the old versions of Java
we're targeting.<sup>[citation needed]</sup></dd>
<dt>ProGuard</dt>
<dd>We're not interested in "protecting" our application, but J2ME
requires <a
href="https://www.guardsquare.com/manual/configuration/examples#microedition">preverification</a>
and ProGuard appears to be the best choice here somehow.</dd>
<dt>MicroEmulator</dt>
<dd>Okay this one's not actually maintained anymore.
But we're just using their stub libraries for the J2ME APIs.</dd>
<dt><a href="https://www.libarchive.org/">bsdtar</a></dt>
<dd>Other ZIP-file creation utilities are available.</dd>
<dt>FFmpeg</dt>
<dd>Other image processing utilities are available.</dd>
</dl>
</p>
<pre>
<samp>$ </samp><kbd>mkdir -p ro/plesoianu lib out/ro/plesoianu out/META-INF</kbd>
<samp>$ </samp><kbd>cd ro/plesoianu</kbd>
<samp>ro/plesoianu$ </samp><kbd>wcurl https://felix.plesoianu.ro/mobile/pocket-gopher/PocketGopher.java</kbd>
<samp> % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 22743 100 22743 0 0 28807 0 0</samp>
<samp>ro/plesoianu$ </samp><kbd>cd ../../lib</kbd>
<samp>lib$ </samp><kbd>wcurl https://repo1.maven.org/maven2/org/microemu/midpapi20/2.0.4/midpapi20-2.0.4.jar https://repo1.maven.org/maven2/org/microemu/cldcapi11/2.0.4/cldcapi11-2.0.4.jar</kbd>
<samp>DL% UL% Dled Uled Xfers Live Total Current Left Speed
100 -- 87390 0 2 0 449k </samp>
<samp>lib$ </samp><kbd>cd ..</kbd>
<samp>$ </samp><kbd>/usr/local/openjdk8/bin/javac -source 1.2 -target 1.2 -d out -bootclasspath lib/midpapi20-2.0.4.jar:lib/cldcapi11-2.0.4.jar ro/plesoianu/PocketGopher.java</kbd>
<samp>warning: [options] source value 1.2 is obsolete and will be removed in a future release
warning: [options] target value 1.2 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
3 warnings</samp>
<samp>$ </samp><kbd>cd out</kbd>
<samp>out$ </samp><kbd>wcurl https://felix.plesoianu.ro/mobile/pocket-gopher/home.txt</kbd>
<samp> % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1245 100 1245 0 0 3383 0 0</samp>
<samp>out$ </samp><kbd>ffmpeg -loglevel error -f pbm_pipe -i - gdimp.png &lt;&lt; EOT</kbd>
<samp>&gt; </samp><kbd>P1</kbd>
<samp>&gt; </samp><kbd>32 32</kbd>
<samp>&gt; </samp><kbd>0000000000000000000000000000000000000000000000000000000000000000000000</kbd>
<samp>&gt; </samp><kbd>0000000000000000000000000000000000000000000000000000000000000001110000</kbd>
<samp>&gt; </samp><kbd>0000000000000000000000001100000000000000000000000000000110000000000000</kbd>
<samp>&gt; </samp><kbd>0000000010000000010000000000011000000001100000000100000000001010011000</kbd>
<samp>&gt; </samp><kbd>0100000000110010000001101001111001110000001001111000110010010010011100</kbd>
<samp>&gt; </samp><kbd>0000110001100010001001001001011000000111110000111010010110010010000000</kbd>
<samp>&gt; </samp><kbd>0000000000111011110000001000000000000000000000111000000010000000000000</kbd>
<samp>&gt; </samp><kbd>0000000011000000001000000000000000000000100000000000000000000000000000</kbd>
<samp>&gt; </samp><kbd>0000000000000000000000111100000000000000000000000000001001111100000000</kbd>
<samp>&gt; </samp><kbd>0000000000000000100000010000000000000000000000001000001100011110000000</kbd>
<samp>&gt; </samp><kbd>0000000000111011100001101100000000000000000011100000011001100000000000</kbd>
<samp>&gt; </samp><kbd>0000000011000001100000000000000000000000010000010000000000000000000000</kbd>
<samp>&gt; </samp><kbd>0000000001000000000000000000000000000000010000000000000000000000000000</kbd>
<samp>&gt; </samp><kbd>0001000000000000000000000000000000000000000000000000000000000000000000</kbd>
<samp>&gt; </samp><kbd>00000000000000000000000000000000000000000000</kbd>
<samp>&gt; </samp><kbd>EOT</kbd>
<samp>out$ </samp><kbd>unix2dos &gt; META-INF/MANIFEST.MF &lt;&lt; EOT</kbd>
<samp>&gt; </samp><kbd>Manifest-Version: 1.0</kbd>
<samp>&gt; </samp><kbd>MicroEdition-Configuration: CLDC-1.1</kbd>
<samp>&gt; </samp><kbd>MicroEdition-Profile: MIDP-2.0</kbd>
<samp>&gt; </samp><kbd>MIDlet-1: Pocket Gopher rebuilt, /gdimp.png, ro.plesoianu.PocketGopher</kbd>
<samp>&gt; </samp><kbd>MIDlet-Description: Rebuild of PocketGopher sources in 2026</kbd>
<samp>&gt; </samp><kbd>MIDlet-Icon: /gdimp.png</kbd>
<samp>&gt; </samp><kbd>MIDlet-Info-URL: http://microblog.ahti.space/nortti/2026-08-25-j2me-in-2026.html</kbd>
<samp>&gt; </samp><kbd>MIDlet-Name: Pocket Gopher rebuilt</kbd>
<samp>&gt; </samp><kbd>MIDlet-Vendor: Felix Pleșoianu, nortti</kbd>
<samp>&gt; </samp><kbd>MIDlet-Version: 1.0</kbd>
<samp>&gt; </samp><kbd>EOT</kbd>
<samp>out$ </samp><kbd>tar -cf ../not-preverified.jar --format zip *</kbd>
<samp>out$ </samp><kbd>cd ..</kbd>
<samp>$ </samp><kbd>proguard -injars not-preverified.jar -outjars pocketgopher-rebuilt.jar -libraryjars lib/midpapi20-2.0.4.jar -libraryjars lib/cldcapi11-2.0.4.jar -dontshrink -dontoptimize -dontobfuscate -microedition</kbd>
<samp>ProGuard, version 7.0.0
Reading program jar [not-preverified.jar] (filtered)
Reading library jar [lib/midpapi20-2.0.4.jar] (filtered)
Reading library jar [lib/cldcapi11-2.0.4.jar] (filtered)
Preparing output jar [pocketgopher-rebuilt.jar] (filtered)
Copying resources from program jar [not-preverified.jar] (filtered)</samp>
</pre>
<p>Inshallah I'll write a proper writeup that exaplains what every bit
here actually is for. For now, my sources were:
<dl>
<dt><a
href="https://fkooman.wordpress.com/2009/02/16/creating-deployable-midlets-with-free-software/"><cite>Creating
deployable MIDlets with free software</cite></a>,
<time>2009</time></dt>
<dd>Pointed me at the proper FOSS software to look at and explained
what ProGuard is actually needed for.</dd>
<dt><a href="https://www.w568w.eu.org/j2me-2026.html"><cite>[EN]
(Much) Faster Way to J2ME Development in 2026</cite></a>, 2026</dt>
<dd>Told me where to get the MicroEmulator stub libraries nowadays
(the answer is Maven Central).</dd>
<dt><a
href="https://github.com/gtrxAC/discord-j2me/blob/main/sdk/compile.sh">sdk/compile.sh</a>
in the <a
href="https://github.com/gtrxAC/discord-j2me">discord-j2me</a>
project</dt>
<dd>Showed the actual commands to run if you are not using an
IDE.</dd>
</dl></p>