Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ void writeProjectZip(OutputStream outputStream) throws IOException {
copyZipEntriesToMap(template.CSS, mergedEntries, ZipEntryType.TEMPLATE_CSS);
copyZipEntriesToMap(template.SOURCE_ZIP, mergedEntries, ZipEntryType.TEMPLATE_SOURCE);
addLocalizationEntries(mergedEntries);
addAutoLocalizationBundleStub(mergedEntries);

try (ZipOutputStream zos = new ZipOutputStream(outputStream)) {
for (Map.Entry<String, byte[]> fileEntry : mergedEntries.entrySet()) {
Expand All @@ -103,43 +102,6 @@ void writeProjectZip(OutputStream outputStream) throws IOException {
}


/**
* Workaround for a bug in shipped Codename One versions (<= 7.0.236) where the
* simulator's AutoLocalizationBundle echoes any missing key back as its own value.
* UIManager.setBundle queries `@im` on every bundle install, gets `"@im"` back from
* the wormhole, tokenizes it, queries `"@im-@im"`, gets `"@im-@im"` back, then
* crashes inside parseTextFieldInputMode on substring(0, indexOf('=')) for a token
* with no `=`. The CSS compiler subprocess (CN1CSSCLI -> Display.init -> JavaSEPort.init
* -> enableAutoLocalizationBundle) hits this on every initializr-generated project.
*
* The proper fix lives in JavaSEPort.AutoLocalizationBundle (don't fabricate values
* for `@`-prefixed meta-keys), but that requires a new framework release. As a
* workaround we ship an empty `Bundle.properties` with `@im=`, which:
* 1. Is preferred by JavaSEPort.findDefaultLocalizationBundleFile over any other
* bundle file in src/main/l10n, so the AutoLocalizationBundle loads it as base.
* 2. Pre-populates `@im=""` in the bundle's underlying Hashtable, so
* AutoLocalizationBundle.get("@im") returns "" (not the fabricated "@im"),
* which has length 0, so setBundle skips the input-mode block entirely.
*
* This is unconditional (added to every generated project) because
* enableAutoLocalizationBundle auto-creates `src/main/l10n` even when the user
* didn't ask for localization bundles, so the crash hits projects without any
* localization too. Remove this stub once the framework fix has shipped and
* cn1.plugin.version is bumped past it.
*/
private void addAutoLocalizationBundleStub(Map<String, byte[]> mergedEntries) throws IOException {
String stub = "# Workaround for the simulator AutoLocalizationBundle @im fabrication crash\n"
+ "# in Codename One <= 7.0.236. Once the framework fix ships, this file can be removed.\n"
+ "# See GeneratorModel.addAutoLocalizationBundleStub for the full story.\n"
+ "@im=\n";
copySingleTextEntryToMap(
"common/src/main/l10n/Bundle.properties",
stub,
mergedEntries,
ZipEntryType.COMMON
);
}

private void addLocalizationEntries(Map<String, byte[]> mergedEntries) throws IOException {
if (!isBareTemplate() || !options.includeLocalizationBundles) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,19 +194,9 @@ private void validateCombination(Template template, IDE ide) throws Exception {
assertMainSourceFile(entries, template, packageName, mainClassName, false);
assertThemeDefaults(entries, template);
assertLocalizationBundles(entries, template, false);
assertAutoLocalizationBundleStub(entries);
assertNoTemplatePlaceholders(entries, template);
}

private void assertAutoLocalizationBundleStub(Map<String, byte[]> entries) {
// Workaround stub for the simulator AutoLocalizationBundle @im fabrication crash
// in shipped CN1 <= 7.0.236. Must be present on every generated project (with or
// without localization bundles) because enableAutoLocalizationBundle auto-creates
// src/main/l10n in the CSS compiler subprocess and hits the crash regardless.
String stub = getText(entries, "common/src/main/l10n/Bundle.properties");
assertContains(stub, "@im=", "Generated project must ship Bundle.properties with @im= to suppress simulator wormhole crash");
}

private void assertThemeDefaults(Map<String, byte[]> entries, Template template) {
if (template != Template.BAREBONES && template != Template.KOTLIN) {
return;
Expand Down
Loading