{
"id": "78544",
"key": "TIMOB-6945",
"fields": {
"issuetype": {
"id": "1",
"description": "A problem which impairs or prevents the functions of the product.",
"name": "Bug",
"subtask": false
},
"project": {
"id": "10153",
"key": "TIMOB",
"name": "Titanium SDK/CLI",
"projectCategory": {
"id": "10100",
"description": "Titanium and related SDKs used in application development",
"name": "Client"
}
},
"fixVersions": [],
"resolution": null,
"resolutiondate": null,
"created": "2011-07-30T05:16:02.000+0000",
"priority": {
"name": "Low",
"id": "4"
},
"labels": [
"cb-tooling"
],
"versions": [
{
"id": "11570",
"description": "",
"name": "Release 1.7.2",
"archived": true,
"released": true,
"releaseDate": "2011-07-21"
},
{
"id": "12580",
"description": "Dual Runtime 1.8.0",
"name": "Release 1.8.0.1",
"archived": true,
"released": true,
"releaseDate": "2011-12-22"
}
],
"issuelinks": [],
"assignee": {
"name": "ingo",
"key": "ingo",
"displayName": "Ingo Muschenetz",
"active": true,
"timeZone": "America/Los_Angeles"
},
"updated": "2016-08-22T22:16:48.000+0000",
"status": {
"description": "This issue was once resolved, but the resolution was deemed incorrect. From here issues are either marked assigned or resolved.",
"name": "Reopened",
"id": "4",
"statusCategory": {
"id": 2,
"key": "new",
"colorName": "blue-gray",
"name": "To Do"
}
},
"components": [
{
"id": "10202",
"name": "Android",
"description": "Android Platform"
}
],
"description": "h2. Problem\r\n\r\nMulti-string i18n substitution (demonstrated in [#Test case 2] and [#Test case 3]) using String.format() fails, while single string substitution ([#Test case 1]) works as expected.\r\n\r\n{panel}\r\nNote that the project must be manually cleaned after any strings.xml files have been modified\r\n{panel}\r\n\r\nh2. Test case\r\n\r\nh3. Test case 1\r\n\r\n* Single string, non-positional substitution works as expected\r\n* Single string, positional substitution works as expected\r\n\r\n{code:lang=javascript|title=app.js}\r\nTi.API.info('The result of the string substitution is: ' + String.format(L('nonPositionalSubstitutionOneString'), 'String1'));\r\nTi.API.info('The result of the string substitution is: ' + String.format(L('positionalSubstitutionOneString'), 'String1'));\r\n{code}\r\n\r\n{code:lang=xml|title=i18n/en/strings.xml}\r\n\r\n\r\n\t%s\r\n\t%1$s\r\n\r\n{code}\r\n\r\n{code:lang=none|title=logcat}\r\n 883 TiAPI I The result of the string substitution is: String1\r\n 883 TiAPI I The result of the string substitution is: String1\r\n{code}\r\n\r\nh2. Test case 2\r\n\r\n* Multiple string, non-positional substitution fails\r\n\r\n{code:lang=javascript|title=app.js}\r\nTi.API.info('The result of the string substitution is: ' + String.format(L('nonPositionalSubstitutionThreeString'), 'String1', 'String2', 3));\r\n{code}\r\n\r\n{code:lang=xml|title=i18n/en/strings.xml}\r\n\r\n\r\n\t%s %s %d\r\n\r\n{code}\r\n\r\n{code:lang=none|title=console}\r\n[ERROR] Error generating R.java from manifest\r\n[ERROR] /home/appcel/Titanium Studio Workspace/testing10/build/android/res/values/strings.xml:3: error: Multiple substitutions specified in non-positional format; did you mean to add the formatted=\"false\" attribute?\r\n[ERROR] /home/appcel/Titanium Studio Workspace/testing10/build/android/res/values/strings.xml:3: error: Unexpected end tag string\r\n{code}\r\n\r\n{code:lang=none|title=logcat}\r\n 909 TitaniumModule E (KrollRuntimeThread) [248,1369] Error in string format\r\n 909 TitaniumModule E java.lang.NullPointerException\r\n 909 TitaniumModule E \tat ti.modules.titanium.TitaniumModule.stringFormat(TitaniumModule.java:285)\r\n 909 TitaniumModule E \tat org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)\r\n 909 TitaniumModule E \tat org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:107)\r\n 909 TitaniumModule E \tat org.appcelerator.kroll.KrollRuntime.handleMessage(KrollRuntime.java:207)\r\n 909 TitaniumModule E \tat org.appcelerator.kroll.runtime.v8.V8Runtime.handleMessage(V8Runtime.java:127)\r\n 909 TitaniumModule E \tat android.os.Handler.dispatchMessage(Handler.java:95)\r\n 909 TitaniumModule E \tat android.os.Looper.loop(Looper.java:123)\r\n 909 TitaniumModule E \tat org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:102)\r\n 909 TiAPI I The result of the string substitution is: null\r\n{code}\r\n\r\nh2. Test case 3\r\n\r\n* Multiple string, positional substitution fails\r\n\r\n{code:lang=javascript|title=app.js}\r\nTi.API.info('The result of the string substitution is: ' + String.format(L('positionalSubstitutionThreeString'), 'String1', 'String2', 3));\r\n{code}\r\n\r\n{code:lang=xml|title=i18n/en/strings.xml}\r\n%3$d %2$s %1$s\r\n{code}\r\n\r\nNo error produced in console.\r\n\r\n{code:lang=none|title=logcat}\r\n 983 TitaniumModule E (KrollRuntimeThread) [280,1472] Error in string format\r\n 983 TitaniumModule E java.lang.NullPointerException\r\n 983 TitaniumModule E \tat ti.modules.titanium.TitaniumModule.stringFormat(TitaniumModule.java:285)\r\n 983 TitaniumModule E \tat org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)\r\n 983 TitaniumModule E \tat org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:107)\r\n 983 TitaniumModule E \tat org.appcelerator.kroll.KrollRuntime.handleMessage(KrollRuntime.java:207)\r\n 983 TitaniumModule E \tat org.appcelerator.kroll.runtime.v8.V8Runtime.handleMessage(V8Runtime.java:127)\r\n 983 TitaniumModule E \tat android.os.Handler.dispatchMessage(Handler.java:95)\r\n 983 TitaniumModule E \tat android.os.Looper.loop(Looper.java:123)\r\n 983 TitaniumModule E \tat org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:102)\r\n 983 TiAPI I The result of the string substitution is: null\r\n{code}\r\n\r\n\r\n\r\nh2. Discussions\r\n\r\nThe original reporter prompted the above investigation, and provided the following information about Titanium 1.7.X where there was a slightly different message\r\n\r\n{code}\r\n* Titanium SDK version: 1.7.2\r\n* Platform & version: Android 2.3\r\n* Device Details: Android emulator\r\n* Host Operating System: Windows Vista\r\n* Titanium Studio version: Titanium Studio, build: 1.0.2.201107130739\r\n{code}\r\n\r\n{code}\r\nIf i use % placeholder inside the language strings, the building is stopped! If i remove the %, everything works like expected\r\n\r\nThe following configuration of my string.xml dont work!\r\n\r\n\r\n\r\n Page %d of %d\r\n\r\n\r\nThis is the output in my adb log.\r\n\r\nThe errormessage is *{{\"Multiple substitutions specified in non-positional format; did you mean to add the formatted=\"false\" attribute?\"}}*\r\n\r\n[DEBUG] D:\\development\\enviroment\\Android\\android-sdk\\platform-tools\\aapt.exe package -m -J D:\\development\\workspaces\\titanium-studio\\meintest\\build\\android\\gen\r\n -M D:\\development\\workspaces\\titanium-studio\\meintest\\build\\android\\AndroidManifest.xml -S D:\\development\\workspaces\\titanium-studio\\meintest\\build\\android\\res\r\n -I D:\\development\\enviroment\\Android\\android-sdk\\platforms\\android-7\\android.jar\r\n[ERROR] D:\\development\\workspaces\\titanium-studio\\meintest\\build\\android\\res\\values\\strings.xml:23: error: Multiple substitutions specified in non-positional format; did you mean to add the formatted=\"false\" attribute?\r\n[ERROR] D:\\development\\workspaces\\titanium-studio\\meintest\\build\\android\\res\\values\\strings.xml:23: error: Unexpected end tag string\r\n[ERROR] Error generating R.java from manifest\r\n\r\n{code} \r\n\r\n\r\nh2. Workaround\r\n\r\nSee [this stackoverflow.com thread|http://stackoverflow.com/questions/4414389/android-xml-percent-symbol/4417333#4417333]\r\n\r\nUse {{formatted=\"false\"}} for each element of the {{strings.xml}} file where multiple placeholders are used.\r\n\r\nWorks as expected on Android 2.2+ & Titanium SDK version: 2.0.0 (03/15/12 07:02 c822d01).\r\n\r\nh3. Test Case 4\r\n\r\n{code:lang=xml|title=/i18n/en/strings.xml}\r\n\r\n\r\n\tYou say %2$s and I say %1$s!\r\n\thello\r\n\tgoodbye\r\n\r\n{code}\r\n\r\n{code:lang=javascript|title=app.js}\r\nvar i18nError = '';\r\nTi.API.info(String.format(L('phrase'), L('greeting', i18nError), L('signoff', i18nError)));\r\n{code}\r\n\r\n",
"attachment": [],
"flagged": false,
"summary": "Android: i18n - Multi-string substitution using String.format() fails",
"creator": {
"name": "greenphp",
"key": "greenphp",
"displayName": "Andreas",
"active": true,
"timeZone": "America/Los_Angeles"
},
"subtasks": [],
"reporter": {
"name": "greenphp",
"key": "greenphp",
"displayName": "Andreas",
"active": true,
"timeZone": "America/Los_Angeles"
},
"environment": "* Titanium SDK version: 1.8.0.1 (12/22/11 13:09 fbdc96f) (official release)\r\n* Runtime: v8\r\n* Google APIs Android 2.2\r\n* Titanium Studio, build: 1.0.8.201112282257\r\n* Ubuntu 10.04\r\n\r\n",
"comment": {
"comments": [
{
"id": "161603",
"author": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"body": "Thank you for raising this ticket. In order to progress it, please add the missing information in the format and places requested in the guidelines at [Jira Ticket Checklist|http://wiki.appcelerator.org/display/guides/Contributing+to+Titanium#ContributingtoTitanium-Summary%3AJiraTicketChecklist].\r\n\r\nMany thanks in advance",
"updateAuthor": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"created": "2011-08-02T16:54:17.000+0000",
"updated": "2011-08-02T16:54:17.000+0000"
},
{
"id": "161649",
"author": {
"name": "greenphp",
"key": "greenphp",
"displayName": "Andreas",
"active": true,
"timeZone": "America/Los_Angeles"
},
"body": "Titanium SDK version: 1.7.2\r\nPlatform & version: Android 2.3\r\nDevice Details: Android emulator\r\nHost Operating System: Windows Vista\r\nTitanium Studio version: Titanium Studio, build: 1.0.2.201107130739",
"updateAuthor": {
"name": "greenphp",
"key": "greenphp",
"displayName": "Andreas",
"active": true,
"timeZone": "America/Los_Angeles"
},
"created": "2011-08-03T04:27:00.000+0000",
"updated": "2011-08-03T04:27:00.000+0000"
},
{
"id": "161679",
"author": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"body": "Thank you, Andreas. So that tickets are consistent for the core team, would you move this information to the environment field?\r\n\r\nPlease provide a usecase that demonstrates this issue. See [Creating Good Use-cases|http://wiki.appcelerator.org/display/guides/Contributing+to+Titanium#ContributingtoTitanium-CreatingGoodUsecases] for info about this.\r\n\r\nPlease provide the full log, in a code block as per the checklist instructions.\r\n\r\nThen I can move this ticket.\r\n\r\nCheers",
"updateAuthor": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"created": "2011-08-03T07:38:06.000+0000",
"updated": "2011-08-03T07:38:06.000+0000"
},
{
"id": "163597",
"author": {
"name": "joel.bohrer",
"key": "joel.bohrer",
"displayName": "Joël Bohrer",
"active": true,
"timeZone": "America/Los_Angeles"
},
"body": "Hi,\r\n\r\nI've the same issue. In fact, it's only if you have 2 time \"%\" in the same string (with only one, everything works).\r\n\r\nJoel",
"updateAuthor": {
"name": "joel.bohrer",
"key": "joel.bohrer",
"displayName": "Joël Bohrer",
"active": true,
"timeZone": "America/Los_Angeles"
},
"created": "2011-08-22T02:35:53.000+0000",
"updated": "2011-08-22T02:35:53.000+0000"
},
{
"id": "165198",
"author": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"body": "Andreas\n\nWhen you have had time to address the issues I mentioned before, you are welcome to reopen this ticket. Many thanks.",
"updateAuthor": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"created": "2011-09-07T07:01:22.000+0000",
"updated": "2011-09-07T07:01:22.000+0000"
},
{
"id": "177239",
"author": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"body": "In order for me to escalate it to the core team, all the fields must be complete. Please check it against the [JIRA Ticket Checklist|https://wiki.appcelerator.org/display/guides/How+to+Submit+a+Bug+Report#HowtoSubmitaBugReport-JIRATicketChecklist], and add any missing information.\r\n\r\nFurthermore, a test case must run without modification, as per the [Creating a Test Case|https://wiki.appcelerator.org/display/guides/How+to+Submit+a+Bug+Report#HowtoSubmitaBugReport-CreatingaTestCase] section.\r\n",
"updateAuthor": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"created": "2011-12-27T06:32:59.000+0000",
"updated": "2011-12-27T06:32:59.000+0000"
},
{
"id": "186602",
"author": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"body": "\r\nThe following test case, where multiple substitution placemarks are used in strings.xml, gives the error message below.\r\n\r\nh4. Environment\r\n\r\n* Titanium SDK version: 2.0.0 (03/15/12 07:02 c822d01)\r\n* Android APIs 2.3.3\r\n* v8\r\n\r\nh4. Test case\r\n\r\n{code:lang=xml|title=/i18n/en/strings.xml}\r\n\r\n\r\n\t%s %s %d\r\n\r\n{code}\r\n\r\nWith an empty app.js, launch the application.\r\n\r\nh4. Log\r\n\r\n{code:lang=none|title=console}\r\n[ERROR] Error generating R.java from manifest\r\n[ERROR] /home/appcel/Titanium Studio Workspace/testing10/build/android/res/values/strings.xml:5: error: Multiple substitutions specified in non-positional format; did you mean to add the formatted=\"false\" attribute?\r\n[ERROR] /home/appcel/Titanium Studio Workspace/testing10/build/android/res/values/strings.xml:5: error: Unexpected end tag string\r\n{code}\r\n",
"updateAuthor": {
"name": "pdowsett",
"key": "pdowsett",
"displayName": "Paul Dowsett",
"active": true,
"timeZone": "Europe/London"
},
"created": "2012-03-15T07:52:27.000+0000",
"updated": "2012-03-15T07:52:27.000+0000"
},
{
"id": "273899",
"author": {
"name": "ygbr",
"key": "ygbr",
"displayName": "Ygor Lemos",
"active": true,
"timeZone": "America/Sao_Paulo"
},
"body": "Any updates on this? If using formatted=\"true\" is required for Android now, it should be reflected on the documentation.\r\n\r\nI have searched the 3.X docs and the appcelerator wiki and found no mentions of the formatted=\"false\" problem with Android, had to find this on JIRA in order to fix my printf localized strings.\r\n\r\nPlease at least update https://wiki.appcelerator.org/display/guides/Internationalization so users know this is the way to solve it for now.",
"updateAuthor": {
"name": "ygbr",
"key": "ygbr",
"displayName": "Ygor Lemos",
"active": true,
"timeZone": "America/Sao_Paulo"
},
"created": "2013-10-04T22:51:01.000+0000",
"updated": "2013-10-04T22:51:01.000+0000"
}
],
"maxResults": 10,
"total": 10,
"startAt": 0
}
}
}