Dissapearing tabs

We experience a strange issue with dissapearing tabs from tabpanels in Servoy 6.0.8 smartclient.
The tabs are gone when this error occurs in the servoy_log:

2013-01-31 16:26:19,168 ERROR [AWT-EventQueue-0] com.servoy.j2db.util.Debug - Destroyed DataAdapterList FormController[form: rel_organisation_pan_contact,destroyed:true] was still attached to the record, removing it, currentRecord: null [3AB392D7-0603-484D-961A-564BAD14F5D4 mSTB_start]
java.lang.RuntimeException
	at com.servoy.j2db.dataprocessing.DataAdapterList.valueChanged(DataAdapterList.java:442)
	at com.servoy.j2db.dataprocessing.Record.fireJSModificationEvent(Record.java:382)
	at com.servoy.j2db.dataprocessing.Record.notifyChange(Record.java:820)
	at com.servoy.j2db.dataprocessing.Row.fireNotifyChange(Row.java:96)
	at com.servoy.j2db.dataprocessing.RowManager.fireRowNotifyChanges(RowManager.java:1273)
	at com.servoy.j2db.dataprocessing.RowManager.foundSetChanged(RowManager.java:1224)
	at com.servoy.j2db.dataprocessing.FoundSetManager$GlobalFoundSetEventListener.foundSetChanged(FoundSetManager.java:1924)
	at com.servoy.j2db.dataprocessing.FoundSetManager$GlobalFoundSetEventListener.foundSetCreated(FoundSetManager.java:1909)
	at com.servoy.j2db.dataprocessing.FoundSetManager$GlobalFoundSetEventListener.foundSetsCreated(FoundSetManager.java:1897)
	at com.servoy.j2db.dataprocessing.FoundSetManager.getRelatedFoundSet(FoundSetManager.java:553)
	at com.servoy.j2db.dataprocessing.FoundSet.getRelatedFoundSet(FoundSet.java:4954)
	at com.servoy.j2db.dataprocessing.Record.getRelatedFoundSet(Record.java:661)
	at com.servoy.j2db.dataprocessing.Record.getValue(Record.java:251)
	at com.servoy.j2db.dataprocessing.Record.get(Record.java:422)
	at com.servoy.j2db.scripting.SelectedRecordScope.get(SelectedRecordScope.java:105)
	at org.mozilla.javascript.ScriptableObject.getProperty(ScriptableObject.java:1641)
	at org.mozilla.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.java:1739)
	at org.mozilla.javascript.ScriptRuntime.name(ScriptRuntime.java:1678)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3752)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2680)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:166)
	at com.servoy.j2db.scripting.ScriptEngine.executeFunction(ScriptEngine.java:537)
	at com.servoy.j2db.debug.RemoteDebugScriptEngine.executeFunction(RemoteDebugScriptEngine.java:392)
	at com.servoy.j2db.FormController.executeFunction(FormController.java:4072)
	at com.servoy.j2db.FormController.executeFormMethod(FormController.java:4394)
	at com.servoy.j2db.FormController.executeOnRecordSelect(FormController.java:4332)
	at com.servoy.j2db.FormController.refreshAllPartRenderers(FormController.java:2239)
	at com.servoy.j2db.FormController.valueChanged(FormController.java:2311)
	at com.servoy.j2db.FormController.notifyVisible(FormController.java:3086)
	at com.servoy.j2db.smart.dataui.FormLookupPanel.notifyVisible(FormLookupPanel.java:222)
	at com.servoy.j2db.smart.dataui.SpecialTabPanel.notifyVisible(SpecialTabPanel.java:225)
	at com.servoy.j2db.dataprocessing.DataAdapterList.notifyVisible(DataAdapterList.java:514)
	at com.servoy.j2db.smart.dataui.DataRenderer.notifyVisible(DataRenderer.java:274)
	at com.servoy.j2db.FormController.notifyVisible(FormController.java:3155)
	at com.servoy.j2db.smart.dataui.FormLookupPanel.notifyVisible(FormLookupPanel.java:222)
	at com.servoy.j2db.smart.dataui.SpecialTabPanel.notifyVisible(SpecialTabPanel.java:225)
	at com.servoy.j2db.dataprocessing.DataAdapterList.notifyVisible(DataAdapterList.java:514)
	at com.servoy.j2db.smart.dataui.DataRenderer.notifyVisible(DataRenderer.java:274)
	at com.servoy.j2db.FormController.notifyVisible(FormController.java:3155)
	at com.servoy.j2db.FormManager.showFormInMainPanel(FormManager.java:738)
	at com.servoy.j2db.FormManager.showFormInMainPanel(FormManager.java:597)
	at com.servoy.j2db.scripting.JSApplication.js_showForm(JSApplication.java:1956)
	at sun.reflect.GeneratedMethodAccessor335.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:179)
	at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:367)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3666)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2680)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:166)
	at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:387)
	at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3134)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:165)
	at com.servoy.j2db.scripting.ScriptEngine.executeFunction(ScriptEngine.java:537)
	at com.servoy.j2db.debug.RemoteDebugScriptEngine.executeFunction(RemoteDebugScriptEngine.java:392)
	at com.servoy.j2db.FormController.executeFunction(FormController.java:4072)
	at com.servoy.j2db.FormController.executeFunction(FormController.java:3951)
	at com.servoy.j2db.FormController.executeFunction(FormController.java:3873)
	at com.servoy.j2db.FormController$ScriptExecuter.executeFunction(FormController.java:3728)
	at com.servoy.j2db.ui.BaseEventExecutor.fireEventCommand(BaseEventExecutor.java:271)
	at com.servoy.j2db.ui.BaseEventExecutor.fireActionCommand(BaseEventExecutor.java:217)
	at com.servoy.j2db.smart.dataui.AbstractScriptLabel$5.mouseReleased(AbstractScriptLabel.java:988)
	at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(Unknown Source)
	at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at com.servoy.j2db.gui.FixedJTable.processMouseEvent(FixedJTable.java:150)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

We have no clue what causes the error and why these tabs dissapear.
Fact is that the dissapearing tabs are set on the tabpanel by using .addTab(). The tabs dissapear after using our solution for aprox 20 min…
Anyone any tips or know-abouts?

Is the form in the tab a real form or a form-instance?

swingman:
Is the form in the tab a real form or a form-instance?

The tabform(s) are real-good-ol’ Servoy forms. Not build using SOM, if that’s what you mean :wink:
We also tried to figure out if this issue occured by using SOM or form manipulation using .recreateUI() or something, but that’s not the case here, too…

that exception is a warning that something hangs, but not directly the problem
If a tab disappears is it destroyed?
Can you add logging to the onUnload event? So that you can see if it really is just destroyed.

Are you reusing those forms that you call addTab on in different tabpanels or as main form?

is the tab itself gone (so the thing you select on the form)
or just the contents (it stays blank)

When do you add tab? Is that in the onload of that form?
If it is really the tab itself are you sure that the parent form is not unloaded and then reloaded (as a fresh thing)

jcompagner:
that exception is a warning that something hangs, but not directly the problem
If a tab disappears is it destroyed?

It looks like that tab is not destroyed, but only invisible. As if it’s just not painted.

Can you add logging to the onUnload event? So that you can see if it really is just destroyed.

It’s pretty hard to reproduce (and tabs dissapear elswhere in the application), so an onUnload might not show the issue. But we’ll try to see if we can see something happening using logging on onUnload

Are you reusing those forms that you call addTab on in different tabpanels or as main form?

Nope, these tabforms are unique and dedicated

is the tab itself gone (so the thing you select on the form) or just the contents (it stays blank)

The tab itself is gone.

When do you add tab? Is that in the onload of that form?

The dissapearing tabs are added during a user login method. Some tabs need to be added when defining user specific data.

If it is really the tab itself are you sure that the parent form is not unloaded and then reloaded (as a fresh thing)

I can’t tell what the issue really is. Fact is that tabs dissapear randomly during a session.
Please let me know if you need more info, we’ll probably will have a more indept debugging session about this strange behaviour :wink:

IF you only do addTab() like

forms.myform.elements.tabpanel.addTab(something)

At login

then it is for me completely logical then you lose them at one point in time
Because that “forms.myform” can be destroyed at any point in time…

Then when a user accesses it (maybe the first time, maybe a second time) the “forms.myform” is recreated…
Without your tabs…

So if you do it at login, Don’t touch all those runtime forms (forms.xxxx)
it seems way more that you should do that through solution model, so that for that session if the form is unloaded/destroyed and recreated it will have that extra tab.

Or you have to do it in the onload of that main form having that tabpanel element…

jcompagner:
IF you only do addTab() like
forms.myform.elements.tabpanel.addTab(something)
At login
then it is for me completely logical then you lose them at one point in time
Because that “forms.myform” can be destroyed at any point in time…

This should never be the case. Added tabs should ALLWAYS stay where they are in a user session, no matter if you add them during login or onLoad.
We don’t destroy (in code) the main tabpanel forms using SOM or something, so these tabs should just plain stay where they are…

No they will not! They never have and never will.

If you just do stuff on runtime forms (forms.xxxx.elements.xxxx.yyyy)
then that is live for THAT instance as long as that one is alive.
But if a user is opening up more and more forms, then we will destroy forms that are least recently used to clean up memory (else out of mem will happen)
That means runtime form instance is destroyed. will be gone, just like all runtime changes you did to it.

And when that runtime form is recreated it will be created how it is specified in design time/ solution model.
So if you at logon want to configure forms you should do it with the solution model, thats exactly why we have the solution model.
That is also way faster (because many forms that you now touch are not created)

jcompagner:
But if a user is opening up more and more forms, then we will destroy forms that are least recently used to clean up memory (else out of mem will happen)
That means runtime form instance is destroyed. will be gone, just like all runtime changes you did to it.

Right… that could explain indeed our issue here. Thanks for pointing that out Johan! I wasn’t aware of this ‘clean up memory’ behaviour…
We’ll try an alternative approace for setting those tabs and keep you posted about our findings.

Johan, it looks like your comment pointed indeed to our issue. Instead of placing tabs using .addTab() in a one-time login method, we now put those tabs on the forms using onLoad.
So far no tabs did dissapear, so thanks again for your input!