App crashes when put in background on every screen that uses rememberSaveable with mutableStateOf - android-jetpack-compose

This crash is seen when using something like var selectedOption by rememberSaveable { mutableStateOf("") } inside a NavHost destination.
Currently using "androidx.navigation:navigation-compose:2.5.2
This issue has been seen before and is similar to this other question asked in 2021
However, the fixes suggested then do not work now and also the suggestions from this Google Issue Tracker do not solve the issue.
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = [Landroidx.compose.runtime.MutableState;)
at android.os.Parcel.writeSerializable(Parcel.java:1833)
at android.os.Parcel.writeValue(Parcel.java:1780)
at android.os.Parcel.writeList(Parcel.java:1045)
at android.os.Parcel.writeValue(Parcel.java:1729)
at android.os.Parcel.writeMapInternal(Parcel.java:896)
at android.os.Parcel.writeMap(Parcel.java:878)
at android.os.Parcel.writeValue(Parcel.java:1694)
at android.os.Parcel.writeMapInternal(Parcel.java:896)
at android.os.Parcel.writeMap(Parcel.java:878)
at android.os.Parcel.writeValue(Parcel.java:1694)
at android.os.Parcel.writeList(Parcel.java:1045)
at android.os.Parcel.writeValue(Parcel.java:1729)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
...
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4505)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.io.NotSerializableException: androidx.compose.runtime.ParcelableSnapshotMutableState
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1434)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1230)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
at android.os.Parcel.writeSerializable(Parcel.java:1828)
at android.os.Parcel.writeValue(Parcel.java:1780) 
at android.os.Parcel.writeList(Parcel.java:1045) 
at android.os.Parcel.writeValue(Parcel.java:1729) 
at android.os.Parcel.writeMapInternal(Parcel.java:896) 
at android.os.Parcel.writeMap(Parcel.java:878) 
...

Related

Unable to execute any StrutsTestCase using Struts2-Junit-Plugin, action method is null

First of all sorry if I don't explain it clearly enough, I will try to do my best. Recently I switched from C/C# to Java, and I'm a bit overwhelmed.
I'm working on a project that is using Struts2+Hibernate (I'm not using Spring); the idea was to use the struts2-JUnit-plugin to test the actions.
I followed the strut2-junit-plugin tutorial without success and after a lot of research and trying all the possible solutions posted everywhere I couldn't find the good one.
The "issues" (because I'm not really sure whether this is an issue or not...) I have is that when I try to run a StrutsTestCase, during the setUp:
super.setUp();
initServletMockObjects();
setupBeforeInitDispatcher();
dispatcher = initDispatcher(dispatcherInitParams);
setupAfterInitDispatcher(dispatcher);
When calling dispatcher = initDispatcher(dispatcherInitParams), dispatcherInitParams is null and it throws the following stack trace:
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
ERROR CdiObjectFactory [findBeanManager]: Could not find BeanManager instance for any given JNDI key, giving up
ERROR CdiObjectFactory Struts2 CDI integration could not be initialized.
ERROR DefaultConversionPropertiesProcessor Conversion registration error
java.lang.NullPointerException
at org.apache.struts2.cdi.CdiObjectFactory.getInjectionTarget(CdiObjectFactory.java:175)
at org.apache.struts2.cdi.CdiObjectFactory.buildBean(CdiObjectFactory.java:148)
at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:177)
at com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator.createTypeConverter(DefaultTypeConverterCreator.java:40)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.loadConversionProperties(DefaultConversionPropertiesProcessor.java:86)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.processRequired(DefaultConversionPropertiesProcessor.java:68)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.init(DefaultConversionPropertiesProcessor.java:59)
at com.opensymphony.xwork2.inject.InitializableFactory.create(InitializableFactory.java:45)
at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:52)
at com.opensymphony.xwork2.inject.ContainerBuilder$3.create(ContainerBuilder.java:118)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:626)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:623)
at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:555)
at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:623)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:187)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:957)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:463)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:496)
at org.apache.struts2.util.StrutsTestCaseHelper.initDispatcher(StrutsTestCaseHelper.java:44)
at org.apache.struts2.StrutsTestCase.initDispatcher(StrutsTestCase.java:236)
at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:216)
at com.xxxx.xxxxx.xx.xxx.PasswordActionTest.setUp(PasswordActionTest.java:31)
at junit.framework.TestCase.runBare(TestCase.java:139)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
ERROR DefaultConversionPropertiesProcessor Conversion registration error
java.lang.NullPointerException
at org.apache.struts2.cdi.CdiObjectFactory.getInjectionTarget(CdiObjectFactory.java:175)
at org.apache.struts2.cdi.CdiObjectFactory.buildBean(CdiObjectFactory.java:148)
at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:177)
at com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator.createTypeConverter(DefaultTypeConverterCreator.java:40)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.loadConversionProperties(DefaultConversionPropertiesProcessor.java:86)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.process(DefaultConversionPropertiesProcessor.java:64)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.init(DefaultConversionPropertiesProcessor.java:60)
at com.opensymphony.xwork2.inject.InitializableFactory.create(InitializableFactory.java:45)
at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:52)
at com.opensymphony.xwork2.inject.ContainerBuilder$3.create(ContainerBuilder.java:118)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:626)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:623)
at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:555)
at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:623)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:187)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:957)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:463)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:496)
at org.apache.struts2.util.StrutsTestCaseHelper.initDispatcher(StrutsTestCaseHelper.java:44)
at org.apache.struts2.StrutsTestCase.initDispatcher(StrutsTestCase.java:236)
at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:216)
at com.xxx.xxxx.xxx.xxxx.PasswordActionTest.setUp(PasswordActionTest.java:31)
at junit.framework.TestCase.runBare(TestCase.java:139)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
After this, even that I got the error, I can continue testing, for instance, the following test:
#Test
public void testGetActionProxy() throws Exception {
//set parameters before calling getActionProxy
PasswordUpdate pu = new PasswordUpdate();
pu.setCurrentPassword("current");
pu.setNewPassword("new");
pu.setNewPasswordConfirm("new");
request.setParameter("passwordUpdate.currentPassword", pu.getCurrentPassword());
request.setParameter("passwordUpdate.newPassword", pu.getNewPassword());
request.setParameter("passwordUpdate.newPasswordConfirm", pu.getNewPasswordConfirm());
ActionProxy proxy = getActionProxy("/UpdatePassword.action");
assertNotNull(proxy);
PasswordAction action = (PasswordAction) proxy.getAction();
assertNotNull(action);
String result = proxy.execute();
assertEquals(Action.SUCCESS, result);
assertNotNull(action.getPasswordUpdate());
assertEquals("current", action.getPasswordUpdate().getCurrentPassword());
assertEquals("new", action.getPasswordUpdate().getNewPassword());
assertEquals("new", action.getPasswordUpdate().getNewPasswordConfirm());
}
The second issue is that it doesn't seem to find the action when calling:
ActionProxy proxy = getActionProxy("/UpdatePassword.action");
It's throwing an exception inside getActionProxy:
protected ActionProxy getActionProxy(String uri) {
request.setRequestURI(uri);
ActionMapping mapping = getActionMapping(request);
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, new HashMap<String, Object>(), true, false);
initActionContext(proxy.getInvocation().getInvocationContext());
// this is normally done in onSetUp(), but we are using Struts internal
// objects (proxy and action invocation)
// so we have to hack around so it works
ServletActionContext.setServletContext(servletContext);
ServletActionContext.setRequest(request);
ServletActionContext.setResponse(response);
return proxy;
}
At this point String method is null and the following call is throwing an exception:
ActionProxy proxy =
config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, new HashMap(), true, false);
Any idea before I give up?
Thank you!
In case someone else ends up in this post with the same issue
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
ERROR CdiObjectFactory [findBeanManager]: Could not find BeanManager instance for any given JNDI key, giving up
ERROR CdiObjectFactory Struts2 CDI integration could not be initialized.
ERROR DefaultConversionPropertiesProcessor Conversion registration error
You can fix this by excluding from your configuration struts2-cdi-plugin

UnsatisfiedLinkError using JSNI with vaadin

I have created a Vaadin project, and I used JSNI for scripting. But when execution reaches at JSNI script, it shows an error.
java.lang.UnsatisfiedLinkError: com.yty.cws.CiwsUI.jsniDemo()V
at com.yty.cws.CiwsUI.jsniDemo(Native Method) ~[classes/:na]
at com.yty.cws.CiwsUI.lambda$0(CwsUI.java:31) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_92]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_92]
The following is my sample code.
public class CiwsUI extends UI{
private static final long serialVersionUID = 5275145103992848572L;
VerticalLayout mainLayout=new VerticalLayout();
private TextField txtName=new TextField();
private Button btnJSNI=new Button("JSNI");
#Override
protected void init(VaadinRequest request) {
mainLayout.addComponents(txtName,btnJSNI);
setContent(mainLayout);
mainLayout.setComponentAlignment(txtName, Alignment.MIDDLE_CENTER);
mainLayout.setComponentAlignment(btnJSNI, Alignment.MIDDLE_CENTER);
btnJSNI.addClickListener(e->{
System.out.println("Clicked");
jsniDemo();
});
}
private native void jsniDemo()/*-{
$wnd.alert("Hai JSNI");
}-*/;
}
Any help is greatly appreciated.
If you look at the differences between GWT & Vaadin you'll notice that besides the cliend-side API, Vaadin also has a server-side API, and the code you posted falls into that category. Searching the Vaadin forum I found this question with your exact problem. Adding below the reply of Henry Sara from the Vaadin dev team:
JSNI is only usable in the client side widgets whereas you are working
on the server side.
Use Window.executeJavaScript("...") (Vaadin 6) or
Root.executeJavaScript("...") (Vaadin 7) if you need to execute
JavaScript from your server side application.
While things may have changed since the answer and Root.executeJavaScript("..."); is now probably JavaScript.getCurrent().execute(...)");, the Vaadin docs offer information on javascript interactions to and from the serverside as well as on js components and extensions and also, you can check the wiki for more examples.

vaadin7: calling navigator from a view renders a stackoverflow error

Given a Main UI which encapsulates a vaadin Navigator, i need to call it from a search view so as to display search results in another view:
1) Main Ui
Navigator nav = new Navigator(this, content)
nav.addView("/search", new SearchView())
...
So everything works fine (with other views), until i implement the search view:
private static final String VIEW_SEARCH= "search"
private static final String VIEW_RESULTS = "searchResults"
in the constructor:
public SearchView() {
UI.getCurrent().getNavigator().addView(VIEW_SEARCH, new SearchView())
UI.getCurrent().getNavigator().addView(VIEW_RESULTS, new SearchResultsView())
which renders a stack overflow error:
*********************************************************
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 844
2013-12-21 19:47:00,772 ERROR [DefaultErrorHandler] -
com.vaadin.server.ServerRpcManager$RpcInvocationException: Unable to invoke method click in com.vaadin.shared.ui.button.ButtonServerRpc
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:170)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
at com.vaadin.server.communication.ServerRpcHandler.handleBurst(ServerRpcHandler.java:207)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:111)
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:91)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:37)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1382)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:238)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at grails.plugin.springsecurity.web.filter.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:102)
at grails.plugin.springsecurity.web.filter.DebugFilter.doFilter(DebugFilter.java:69)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.reflect.InvocationTargetException
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:168)
... 15 more
Caused by: com.vaadin.event.ListenerMethod$MethodException: Invocation of method buttonClick in com.webvibes.conquest.ui.KMUI$2 failed.
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:528)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:969)
at com.vaadin.ui.Button.fireClick(Button.java:368)
at com.vaadin.ui.Button$1.click(Button.java:57)
... 16 more
Caused by: java.lang.StackOverflowError
at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.webvibes.conquest.ui.SearchView.<init>(SearchView.groovy:43)
at com.webvibes.conquest.ui.SearchView.<init>(SearchView.groovy:43)
The goal here is pretty basic, the search view handles a Button which opens up a new view for the results with parameters:
KMUI.getCurrent().getNavigator().navigateTo(VIEW_RESULTS)
Thanks for any help.
* UPDATE:
Well, it seems that putting
UI.getCurrent().getNavigator().addView(VIEW_SEARCH, new SearchView())
UI.getCurrent().getNavigator().addView(VIEW_RESULTS, new SearchResultsView())
directly into the main UI does the job,
but, in that case i miss the results constructor to send the results... what is the best way to send results (HashMap) to the reults view:
No signature of method: com.vaadin.navigator.Navigator.navigateTo() is applicable for argument types: (java.lang.String, java.util.HashMap) values: [/searchResults, [total:0, hits:org.compass.core.impl.DefaultCompassDetachedHits#340f9d23, ...]]
Possible solutions: navigateTo(java.lang.String)
KMUI.getCurrent().getNavigator().navigateTo(VIEW_RESULTS, res)
You can use the session to pass parameter to another view.
Check this link for an example:
Setting and reading session attributes

IllegalArgument exception in custom setter after upgrading to JSF2

After upgrading to JSF2 (probably) one special accessor in an .xhtml file generates IllegalArgumentExceptions but I can't really find out why. Running the app on my local JBoss (4.2.2) does not generate this exception but this can be related to a difference between debug and live data.
Following stack trace is generated that I could extract from the production server log:
Caused by: javax.el.ELException: /xy/xy-subtemplate1.xhtml #131,45 value="#{someClass.someProperty}": java.lang.IllegalArgumentException
at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:101)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
... 36 more
Caused by: java.lang.IllegalArgumentException
at sun.reflect.GeneratedMethodAccessor1134.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.el.BeanELResolver.setValue(BeanELResolver.java:108)
at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
at org.apache.el.parser.AstValue.setValue(AstValue.java:114)
at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:93)
... 37 more
someClass is being iterated over in a list and has the following methods to access someProperty:
public int getSomeProperty() {
return this.getSomeRelatedEnum().ordinal();
}
public void setSomeProperty( final int index) {
this.setSomeRelatedEnum( SomeRelatedEnum.fromOrdinal( index) );
}
How can this lead to the IllegalArgumentException mentioned above?
That can happen when the setter method after all expects a different argument type than the one which is provided from EL on.
I guess that it's related to the fact that hardcoded/unconverted numbers in EL are by default treated as long and not as int. Try either changing the int to be long, or providing an explicit integer converter on the input component like so <h:someInput converter="javax.faces.Integer">.
By the way, why don't you just get/set the enum itself directly? Getting/setting the enum by its ordinal is whacky.

JSON converter - stack overflow

I'm trying to convert a domain class into JSON.
def converter = null
try{
converter = events as JSON
} catch(e) {
log.error "error during conversion to JSON"
log.error e
}
return converter.toString()
I always get this error:
org.codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionException: Executing action [findEvents] of controller
[com.geoadapta.geodata.DataAccessJsonController] caused exception:
java.lang.StackOverflowError
at java.lang.Thread.run(Thread.java:619)
Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.StackOverflowError
... 1 more
Caused by: java.lang.StackOverflowError
at org.codehaus.groovy.util.AbstractConcurrentMap.getOrPut(AbstractConcurrentMap.java:20)
at grails.converters.JSON.value(JSON.java:188)
at grails.converters.JSON.convertAnother(JSON.java:160)
at grails.converters.JSON.value(JSON.java:192)
// hundreds of times
at grails.converters.JSON.value(JSON.java:192)
at grails.converters.JSON.convertAnother(JSON.java:160)
at grails.converters.JSON.value(JSON.java:192)
at grails.converters.JSON.convertAnother(JSON.java:160)
at grails.converters.JSON.value(JSON.java:192)
at grails.converters.JSON.convertAnother(JSON.java:160)
at grails.converters.JSON.value(JSON.java:192)
at grails.converters.JSON.convertAnother(JSON.java:160)
at grails.converters.JSON.value(JSON.java:192)
at grails.converters.JSON.convertAnother(JSON.java:160)
at grails.converters.JSON.value(JSON.java:192)
2010-06-23 16:21:28,390 [http-8080-1] DEBUG [/GeoAdaptaApp].[grails] - Disabling the response for futher output
This is the domain class: http://www.copypastecode.com/31527
The only problem I can see is the 'context' reference. But even if I set to 'null', I still get the stack overflow.
My converter is not propagating circular references.
I'd like to debug it and find out which property is causing the problem, but no luck so far.
Any hints?
Cheers
Sorry, would prefer to add this as a comment, but do not have the rep to add comments yet.
In your domain class it sounds like there are several classes that extend off this one, how are you populating the 'events' object? Since you say the context is set to null and that is the only relationship that's defined directly, a list of unintended subclasses in your results is one way that springs to mind for how you could get into such a deep recursion scenario.
To work around the immediate problem so you can do some debugging, have you tried calling:
converter.setRenderDomainClassRelations(false)

Resources