Project

General

Profile

Bug #3370

READ-ONLY attribute error in server log

Added by Eric Faulhaber over 6 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Target version:
-
Start date:
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:

History

#1 Updated by Eric Faulhaber over 6 years ago

  • Subject changed from READ-ONLY attribute error in log to READ-ONLY attribute error in server log
We see this in a customer app. Can also be recreated in Hotel GUI as follows:
  1. Log in.
  2. Click "Check-In..." in the "Available" screen.

Log entry:

[11/13/2017 12:09:54 EST] (UnimplementedFeature:SEVERE) {00000010:00000033:bogus} UNSUPPORTED: READ-ONLY attribute is undefined
java.lang.RuntimeException
        at com.goldencode.p2j.util.UnimplementedFeature.unsupported(UnimplementedFeature.java:351)
        at com.goldencode.p2j.ui.GenericWidget.isReadOnly(GenericWidget.java:667)
        at com.goldencode.hotel.common.adm2.Visual.lambda$null$21(Visual.java:858)
        at com.goldencode.p2j.util.logical.and(logical.java:955)
        at com.goldencode.p2j.util.logical._and(logical.java:756)
        at com.goldencode.hotel.common.adm2.Visual.lambda$null$22(Visual.java:858)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.coreLoop(BlockManager.java:8251)
        at com.goldencode.p2j.util.BlockManager.doLoopWorker(BlockManager.java:8074)
        at com.goldencode.p2j.util.BlockManager.doTo(BlockManager.java:1029)
        at com.goldencode.hotel.common.adm2.Visual.lambda$enableObject$23(Visual.java:809)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:369)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:355)
        at com.goldencode.hotel.common.adm2.Visual.enableObject(Visual.java:786)
        at sun.reflect.GeneratedMethodAccessor680.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invokeImpl(ControlFlowOps.java:5385)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invoke(ControlFlowOps.java:5363)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4424)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:3453)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4101)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4030)
        at com.goldencode.p2j.util.ControlFlowOps.invokeInImpl(ControlFlowOps.java:3986)
        at com.goldencode.p2j.util.ControlFlowOps.invokeIn(ControlFlowOps.java:966)
        at com.goldencode.hotel.common.adm2.Visual.lambda$initializeObject$35(Visual.java:1113)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:369)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:355)
        at com.goldencode.hotel.common.adm2.Visual.initializeObject(Visual.java:914)
        at sun.reflect.GeneratedMethodAccessor677.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invokeImpl(ControlFlowOps.java:5385)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invoke(ControlFlowOps.java:5363)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4424)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:3453)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4101)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4030)
        at com.goldencode.p2j.util.ControlFlowOps.invokeInImpl(ControlFlowOps.java:3986)
        at com.goldencode.p2j.util.ControlFlowOps.runSuper(ControlFlowOps.java:366)
        at com.goldencode.hotel.common.adm2.Containr.lambda$initializeObject$83(Containr.java:3460)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:369)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:355)
        at com.goldencode.hotel.common.adm2.Containr.initializeObject(Containr.java:3303)
        at sun.reflect.GeneratedMethodAccessor757.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invokeImpl(ControlFlowOps.java:5385)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invoke(ControlFlowOps.java:5363)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4424)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:3453)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4101)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4030)
        at com.goldencode.p2j.util.ControlFlowOps.invokeInImpl(ControlFlowOps.java:3986)
        at com.goldencode.p2j.util.ControlFlowOps.runSuper(ControlFlowOps.java:366)
        at com.goldencode.hotel.UpdateStayDialog.lambda$initializeObject$31(UpdateStayDialog.java:1859)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:369)
        at com.goldencode.p2j.util.BlockManager.internalProcedure(BlockManager.java:355)
        at com.goldencode.hotel.UpdateStayDialog.initializeObject(UpdateStayDialog.java:1856)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invokeImpl(ControlFlowOps.java:5385)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invoke(ControlFlowOps.java:5363)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4424)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:3453)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4101)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4030)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:432)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:418)
        at com.goldencode.hotel.UpdateStayDialog.lambda$null$12(UpdateStayDialog.java:1442)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.doBlockWorker(BlockManager.java:7926)
        at com.goldencode.p2j.util.BlockManager.doBlock(BlockManager.java:767)
        at com.goldencode.hotel.UpdateStayDialog.lambda$execute$13(UpdateStayDialog.java:1440)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.BlockManager.externalProcedure(BlockManager.java:343)
        at com.goldencode.p2j.util.BlockManager.externalProcedure(BlockManager.java:317)
        at com.goldencode.hotel.UpdateStayDialog.execute(UpdateStayDialog.java:669)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invokeImpl(ControlFlowOps.java:5385)
        at com.goldencode.p2j.util.ControlFlowOps$InternalEntryCaller.invoke(ControlFlowOps.java:5363)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4424)
        at com.goldencode.p2j.util.ControlFlowOps.invoke(ControlFlowOps.java:3453)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4101)
        at com.goldencode.p2j.util.ControlFlowOps.invokeImpl(ControlFlowOps.java:4030)
        at com.goldencode.p2j.util.ControlFlowOps.invokeWithMode(ControlFlowOps.java:404)
        at com.goldencode.p2j.util.ControlFlowOps.invokeWithMode(ControlFlowOps.java:386)
        at com.goldencode.hotel.AvailRoomsFrame$TriggerBlock0.lambda$body$0(AvailRoomsFrame.java:1752)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.doBlockWorker(BlockManager.java:7926)
        at com.goldencode.p2j.util.BlockManager.doBlock(BlockManager.java:683)
        at com.goldencode.hotel.AvailRoomsFrame$TriggerBlock0.body(AvailRoomsFrame.java:1750)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.Trigger.run(Trigger.java:316)
        at com.goldencode.p2j.ui.LogicalTerminal.lambda$trigger$1(LogicalTerminal.java:9934)
        at com.goldencode.p2j.ui.LogicalTerminal.invokeOnServer(LogicalTerminal.java:15558)
        at com.goldencode.p2j.ui.LogicalTerminal.trigger(LogicalTerminal.java:9934)
        at sun.reflect.GeneratedMethodAccessor641.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.MethodInvoker.invoke(MethodInvoker.java:124)
        at com.goldencode.p2j.net.Dispatcher.processInbound(Dispatcher.java:757)
        at com.goldencode.p2j.net.Conversation.block(Conversation.java:412)
        at com.goldencode.p2j.net.Conversation.waitMessage(Conversation.java:348)
        at com.goldencode.p2j.net.Queue.transactImpl(Queue.java:1170)
        at com.goldencode.p2j.net.Queue.transact(Queue.java:641)
        at com.goldencode.p2j.net.BaseSession.transact(BaseSession.java:271)
        at com.goldencode.p2j.net.HighLevelObject.transact(HighLevelObject.java:211)
        at com.goldencode.p2j.net.RemoteObject$RemoteAccess.invokeCore(RemoteObject.java:1473)
        at com.goldencode.p2j.net.InvocationStub.invoke(InvocationStub.java:145)
        at com.sun.proxy.$Proxy17.waitFor(Unknown Source)
        at com.goldencode.p2j.ui.LogicalTerminal.waitFor(LogicalTerminal.java:6400)
        at com.goldencode.p2j.ui.LogicalTerminal.waitFor(LogicalTerminal.java:6170)
        at com.goldencode.hotel.Emain.lambda$execute$0(Emain.java:43)
        at com.goldencode.p2j.util.Block.body(Block.java:604)
        at com.goldencode.p2j.util.BlockManager.processBody(BlockManager.java:6985)
        at com.goldencode.p2j.util.BlockManager.topLevelBlock(BlockManager.java:6776)
        at com.goldencode.p2j.util.BlockManager.externalProcedure(BlockManager.java:343)
        at com.goldencode.p2j.util.BlockManager.externalProcedure(BlockManager.java:317)
        at com.goldencode.hotel.Emain.execute(Emain.java:41)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.Utils.invoke(Utils.java:1337)
        at com.goldencode.p2j.main.StandardServer$MainInvoker.execute(StandardServer.java:1981)
        at com.goldencode.p2j.main.StandardServer.invoke(StandardServer.java:1476)
        at com.goldencode.p2j.main.StandardServer.standardEntry(StandardServer.java:525)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.goldencode.p2j.util.MethodInvoker.invoke(MethodInvoker.java:124)
        at com.goldencode.p2j.net.Dispatcher.processInbound(Dispatcher.java:757)
        at com.goldencode.p2j.net.Conversation.block(Conversation.java:412)
        at com.goldencode.p2j.net.Conversation.run(Conversation.java:232)
        at java.lang.Thread.run(Thread.java:748)

#2 Updated by Ovidiu Maxiniuc over 6 years ago

I investigated this issue. The root cause of this error is the fact that the READ-ONLY attribute is declared in CommonWidget interface. The attribute only applies to: BROWSE widget (browse and column), Buffer-field object handle, EDITOR widget, FILL-IN widget, MENU-ITEM widget.

Because the attribute is declared for all widgets, the CAN-QUERY function will return yes for other widgets like buttons and comboboxes. This is because the implementation looks for the specific annotation.

The code in common/adm2/visual.p uses the accessibility test first:

IF CAN-QUERY(hField,'read-only':U) AND NOT hField:READ-ONLY THEN

but since the CAN-QUERY returns yes, it will be forced to incorrectly access the default code from GenericWidget that will signal the READ-ONLY is in fact non existent for those widgets.

Solution

We need a new dedicated interface for read-only attribute, which will be implemented only by the above-mentioned widgets.

#3 Updated by Greg Shah over 6 years ago

I agree with the solution.

#4 Updated by Ovidiu Maxiniuc over 6 years ago

I found that CommonHandle.readOnlyError(String) is annotated with @LegacyAttribute(name = "READ-ONLY").

I consider this incorrect. I cannot see any purpose for this annotation, in fact it collides with the real read-only attribute annotation. This method does not define a legacy attribute, it merely print the warning that a specific attribute is not writeable. I think this is a COPY/PASTE bug. I will drop it.

#5 Updated by Ovidiu Maxiniuc over 6 years ago

Greg,
I finished moving the READ-ONLY attribute to a new interface.
Because the introduction of the new interface WriteProtectable the projects needs to be reconverted. Should I create a dedicated new branch or should I merge the changes in 3369a ?

#6 Updated by Ovidiu Maxiniuc over 6 years ago

  • % Done changed from 0 to 90
  • Status changed from New to WIP

#7 Updated by Greg Shah over 6 years ago

I think this needs to be separate from 3369a, so that we don't introduce a delay in getting the most critical changes into the trunk.

#8 Updated by Ovidiu Maxiniuc over 6 years ago

I created 3370a created and committed a patch for this issue. Current revision is 11203. Please review.

#9 Updated by Ovidiu Maxiniuc over 6 years ago

  • Assignee set to Ovidiu Maxiniuc

#10 Updated by Greg Shah over 6 years ago

Code Review Task branch 3370a Revision 11203

The changes look good.

I think you have found a more widespread flaw. Our original implementation of many attributes/methods was "too high" up the inheritance hierarchy. Over the last few years we have been adding new attrs/meths as specifically targeted interfaces that are only implemented in the exact classes needed. Your finding proves this is not only a cleaner approach but it is, in fact, more logically correct too. Although we don't have the time to rework all the old/bad ones now, it is clear that we will have to do this at some point.

Please put this through conversion regression testing. I don't think that extensive runtime testing is needed. Hotel GUI testing is probably enough.

#11 Updated by Ovidiu Maxiniuc over 6 years ago

Indeed, we should have an interface for each P4GL attribute / method. Some of them can be grouped together if they are related (like x and y).

I have already reconverted Hotel GUI with changes from 3370a Revision 11203. There were no issues that I could spot. The are only 5 places in the project where the new interface WriteProtectable is used. I can do a conversion test on majic too.

The @Overwrite annotation was really helpful here, to be sure the widgets that implement the attribute also extend the new interface. And since the implementations of the method are not altered, I think too, that the runtime is not really necessary.

#12 Updated by Ovidiu Maxiniuc over 6 years ago

The conversion test on devsrv01 ended with success. The generated code by 3370a/11203 is unchanged.

#13 Updated by Greg Shah over 6 years ago

Please merge 3370a to trunk.

#14 Updated by Ovidiu Maxiniuc over 6 years ago

  • % Done changed from 90 to 100

Committed revision 11204.
Branch was archived. Notification email was sent to team.

#15 Updated by Greg Shah over 6 years ago

  • Project changed from Bugs to User Interface
  • Status changed from WIP to Closed

Also available in: Atom PDF