java.lang.ClassCastException

There are no available Samebug tips for this exception. Do you have an idea how to solve this issue? A short tip would help users who saw this issue last week.

  • Originally reported as an Alloy issue, this is a platform issue. Setting a property to a string that expects a boolean will work on iOS but throw an exception on Android. Test case: returnKeyEnabled expects boolean, drop the following into a new classic project, build for Android, tap the text field then with or without entering text in the field, tap the Done (return) button to cause the crash. App works as-is on iOS (7.0 simulator) {code} var win = Titanium.UI.createWindow({ backgroundColor:'#fff', layout: 'vertical' }); var txt = Ti.UI.createTextField({ top: 50, width: Ti.UI.FILL, color: 'black', borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED, enableReturnKey: 'true' // change to true to "fix" }); win.add(txt); win.open(); {code} {code} [ERROR] TiApplication: (main) [12383,12383] Sending event: exception on thread: main msg:java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean; Titanium 3.2.0,2013/12/20 10:57,d9182d6 [ERROR] TiApplication: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean [ERROR] TiApplication: at ti.modules.titanium.ui.widget.TiUIText.onEditorAction(TiUIText.java:389) [ERROR] TiApplication: at android.widget.TextView.onEditorAction(TextView.java:4117) [ERROR] TiApplication: at com.android.internal.widget.EditableInputConnection.performEditorAction(EditableInputConnection.java:138) [ERROR] TiApplication: at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:297) [ERROR] TiApplication: at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77) [ERROR] TiApplication: at android.os.Handler.dispatchMessage(Handler.java:99) [ERROR] TiApplication: at android.os.Looper.loop(Looper.java:137) [ERROR] TiApplication: at android.app.ActivityThread.main(ActivityThread.java:5041) [ERROR] TiApplication: at java.lang.reflect.Method.invokeNative(Native Method) [ERROR] TiApplication: at java.lang.reflect.Method.invoke(Method.java:511) [ERROR] TiApplication: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) [ERROR] TiApplication: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) [ERROR] TiApplication: at dalvik.system.NativeStart.main(Native Method) {code}
    via by Tim Poulsen,
  • Originally reported as an Alloy issue, this is a platform issue. Setting a property to a string that expects a boolean will work on iOS but throw an exception on Android. Test case: returnKeyEnabled expects boolean, drop the following into a new classic project, build for Android, tap the text field then with or without entering text in the field, tap the Done (return) button to cause the crash. App works as-is on iOS (7.0 simulator) {code} var win = Titanium.UI.createWindow({ backgroundColor:'#fff', layout: 'vertical' }); var txt = Ti.UI.createTextField({ top: 50, width: Ti.UI.FILL, color: 'black', borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED, enableReturnKey: 'true' // change to true to "fix" }); win.add(txt); win.open(); {code} {code} [ERROR] TiApplication: (main) [12383,12383] Sending event: exception on thread: main msg:java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean; Titanium 3.2.0,2013/12/20 10:57,d9182d6 [ERROR] TiApplication: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean [ERROR] TiApplication: at ti.modules.titanium.ui.widget.TiUIText.onEditorAction(TiUIText.java:389) [ERROR] TiApplication: at android.widget.TextView.onEditorAction(TextView.java:4117) [ERROR] TiApplication: at com.android.internal.widget.EditableInputConnection.performEditorAction(EditableInputConnection.java:138) [ERROR] TiApplication: at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:297) [ERROR] TiApplication: at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77) [ERROR] TiApplication: at android.os.Handler.dispatchMessage(Handler.java:99) [ERROR] TiApplication: at android.os.Looper.loop(Looper.java:137) [ERROR] TiApplication: at android.app.ActivityThread.main(ActivityThread.java:5041) [ERROR] TiApplication: at java.lang.reflect.Method.invokeNative(Native Method) [ERROR] TiApplication: at java.lang.reflect.Method.invoke(Method.java:511) [ERROR] TiApplication: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) [ERROR] TiApplication: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) [ERROR] TiApplication: at dalvik.system.NativeStart.main(Native Method) {code}
    via by Tim Poulsen,
  • When passing custom arguments using the <require> tag on an alloy controller main.xml <Require src="inputText" enableReturnKey="true" /> inputText.xml <Alloy> <View> <TextField id="textField" /> </View> </Alloy> inputText.js var args = arguments[0] || {}; $.textField.enableReturnKey = args.enableReturnKey; On iOS, it works. On Android, the app crashes with a ClassCastException because the string "true" is not boolean true. java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean E/AndroidRuntime( 3277): at ti.modules.titanium.ui.widget.TiUIText.onEditorAction(TiUIText.java:373) E/AndroidRuntime( 3277): at android.widget.TextView.onEditorAction(TextView.java:4594) E/AndroidRuntime( 3277): at com.android.internal.widget.EditableInputConnection.performEditorAction(EditableInputConnection.java:138) E/AndroidRuntime( 3277): at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:297) E/AndroidRuntime( 3277): at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77) E/AndroidRuntime( 3277): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime( 3277): at android.os.Looper.loop(Looper.java:175) E/AndroidRuntime( 3277): at android.app.ActivityThread.main(ActivityThread.java:5279) E/AndroidRuntime( 3277): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime( 3277): at java.lang.reflect.Method.invoke(Method.java:511) E/AndroidRuntime( 3277): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) E/AndroidRuntime( 3277): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) E/AndroidRuntime( 3277): at dalvik.system.NativeStart.main(Native Method) The line being here: https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUIText.java Boolean enableReturnKey = (Boolean) proxy.getProperty(TiC.PROPERTY_ENABLE_RETURN_KEY); This works fine if the attribute is set directly in the destination controller. inputText.xml <Alloy> <View> <TextField id="textField" enableReturnKey="true" /> </View> </Alloy> Alloy is likely doing some lookahead on the proxy to change the xml string "true" to the object true. But this cannot be done when passing an argument through the <Require> tag. The workaround is: var args = arguments[0] || {}; $.textField.enableReturnKey = toBoolean(args.enableReturnKey); function toBoolean(str) { if (!str) { return false; } if (str == "true") { return true; } else if (str == "false") { return false; } return str; } But, this is not very elegant. The iOS proxies likely do some graceful type conversions when looking for booleans, but the Android ones do not. Unfortunately the fix is very difficult. Modify all Android proxies that want non string values, to pass through a utility that checks the type and converts to Boolean instead of a blind cast. Or, developers should understand that they are setting a string value on a boolean attribute in their controllers. I would just accept that and fix my code, but the fact that it works in iOS and not in Android is why this may be considered a bug.
    via by Mauro Parra-Miranda,
  • When passing custom arguments using the <require> tag on an alloy controller main.xml <Require src="inputText" enableReturnKey="true" /> inputText.xml <Alloy> <View> <TextField id="textField" /> </View> </Alloy> inputText.js var args = arguments[0] || {}; $.textField.enableReturnKey = args.enableReturnKey; On iOS, it works. On Android, the app crashes with a ClassCastException because the string "true" is not boolean true. java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean E/AndroidRuntime( 3277): at ti.modules.titanium.ui.widget.TiUIText.onEditorAction(TiUIText.java:373) E/AndroidRuntime( 3277): at android.widget.TextView.onEditorAction(TextView.java:4594) E/AndroidRuntime( 3277): at com.android.internal.widget.EditableInputConnection.performEditorAction(EditableInputConnection.java:138) E/AndroidRuntime( 3277): at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:297) E/AndroidRuntime( 3277): at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77) E/AndroidRuntime( 3277): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime( 3277): at android.os.Looper.loop(Looper.java:175) E/AndroidRuntime( 3277): at android.app.ActivityThread.main(ActivityThread.java:5279) E/AndroidRuntime( 3277): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime( 3277): at java.lang.reflect.Method.invoke(Method.java:511) E/AndroidRuntime( 3277): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) E/AndroidRuntime( 3277): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) E/AndroidRuntime( 3277): at dalvik.system.NativeStart.main(Native Method) The line being here: https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUIText.java Boolean enableReturnKey = (Boolean) proxy.getProperty(TiC.PROPERTY_ENABLE_RETURN_KEY); This works fine if the attribute is set directly in the destination controller. inputText.xml <Alloy> <View> <TextField id="textField" enableReturnKey="true" /> </View> </Alloy> Alloy is likely doing some lookahead on the proxy to change the xml string "true" to the object true. But this cannot be done when passing an argument through the <Require> tag. The workaround is: var args = arguments[0] || {}; $.textField.enableReturnKey = toBoolean(args.enableReturnKey); function toBoolean(str) { if (!str) { return false; } if (str == "true") { return true; } else if (str == "false") { return false; } return str; } But, this is not very elegant. The iOS proxies likely do some graceful type conversions when looking for booleans, but the Android ones do not. Unfortunately the fix is very difficult. Modify all Android proxies that want non string values, to pass through a utility that checks the type and converts to Boolean instead of a blind cast. Or, developers should understand that they are setting a string value on a boolean attribute in their controllers. I would just accept that and fix my code, but the fact that it works in iOS and not in Android is why this may be considered a bug.
    via by Mauro Parra-Miranda,
    • java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean at ti.modules.titanium.ui.widget.TiUIText.onEditorAction(TiUIText.java:389) at android.widget.TextView.onEditorAction(TextView.java:4117) at com.android.internal.widget.EditableInputConnection.performEditorAction(EditableInputConnection.java:138) at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:297) at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method)
    No Bugmate found.