-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8261689: javax/swing/JComponent/7154030/bug7154030.java still fails with "Exception: Failed to hide opaque button" #2790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ith "Exception: Failed to hide opaque button" Slightly adjusted the sequence of the waiting plus set specific min/max sizes on the component and frame. That should get rid of the incomplete painting at the start. Also added the additional screen capture that should show the state of the application after initialization and the area that will be analyzed.
|
👋 Welcome back kizune! A progress list of the required criteria for merging this PR into |
|
@azuev-java The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
| frw = bounds.width - insets.left - insets.right; | ||
| frh = bounds.height - insets.top - insets.bottom; | ||
|
|
||
| imageInit = robot.createScreenCapture(new Rectangle(locx, locy, frw, frh)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the result of this screen capture is unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, accidentally copied line instead of moving it.
aivanov-jdk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should frame be declared as volatile? It's accessed on main thread in finally block.
In addition to it, frame.getBounds() and frame.getInsets() are called on main thread instead of EDT.
| BufferedImage fullScreen = robot.createScreenCapture(screen); | ||
| Graphics g = fullScreen.getGraphics(); | ||
| g.setColor(Color.RED); | ||
| g.drawRect(locx-1, locy-1, frw+1, frh+1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| g.drawRect(locx-1, locy-1, frw+1, frh+1); | |
| g.drawRect(locx - 1, locy - 1, frw + 1, frh + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
| desktop.setMinimumSize(new Dimension(300, 300)); | ||
| desktop.setMaximumSize(new Dimension(300, 300)); | ||
|
|
||
| frame.setContentPane(desktop); | ||
| frame.setSize(300, 300); | ||
| frame.setMinimumSize(new Dimension(350, 350)); | ||
| frame.setMaximumSize(new Dimension(350, 350)); | ||
| frame.pack(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make {{desktop}} larger than 300,300?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will but it forces the invalidation and repainting of the content so test does not fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will but it forces the invalidation and repainting of the content so test does not fail.
Got it! It's the intention to cause additional repaint.
| ImageIO.write(imageInit, "png", new File("imageInit.png")); | ||
| ImageIO.write(imageShow, "png", new File("imageShow.png")); | ||
| ImageIO.write(fullScreen, "png", new File("fullScreenInit.png")); | ||
| throw new Exception("Failed to show opaque button"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest moving saving the images into a new method.
I see the set of images is different each time. Probably it makes sense to save all the images which are non-null, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is necessary. And since this is an existing test i'm trying not to change its overall behavior and having screenshots at other stages of the testing is not beneficial in the test debugging.
| if (Util.compareBufferedImages(imageInit, imageShow)) { | ||
| ImageIO.write(imageInit, "png", new File("imageInit.png")); | ||
| ImageIO.write(imageShow, "png", new File("imageShow.png")); | ||
| ImageIO.write(fullScreen, "png", new File("fullScreenInit.png")); | ||
| throw new Exception("Failed to show non-opaque button"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to move this block above before invokeAndWait to make the sequence of actions consistent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, functionally it will not make any difference, we are analyzing the screenshots and the only thing that matters is at which time screenshot was taken. The only reason we don't take all screenshots in the beginning and analyze them later is to save test run time if test runs early. At the end it is not critical anymore. And as i said this is an existing test so i'm trying not to change it unless it affects its functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree it makes no difference. Yet when you read the test code, the pattern — show or hide the button, take screenshot, analyze it — gets broken. This place is the only exception to the pattern; here the button is shown, screenshot is taken, then the button is hidden and only after hiding the button the screenshot is analyzed, which could give the wrong impression as if the screenshot after hiding the button is being analyzed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, i give up, you won - i'll fix it.
|
|
||
| robot.delay(1000); | ||
| robot.waitForIdle(1000); | ||
| robot.delay(1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt that this is a test issue, 2 seconds was not enough to properly show the frame?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that i tried to reproduce this behavior locally on Ubuntu running this test (and the simplified version of it) literally millions of times. The only time it fails is when it is run on mach5 and even then it fails very rarely - once per hundreds of runs. The changes here - especially forcing the resize - seems to eliminate the problem with mach5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it is a product bug, If the problem is unrelated to the performance and the root cause is in the wrong/broken final layout. Do we want to suggest the same thing if the user will get the same issue in their app?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be a product bug. Or it might be something specific to the machines with mach5 system. Or to some specific machine having hardware issue (i noticed that in my case all failures happened on one specific Linux test system). That's the problem. I have a simplified test case that should check for that specific problem and i'm running a dedicated Linux host in my home office with the same OS version than problematic machine that does nothing but runs this test in interactive mode for days. Today only i ran this test over 700000 times - 0 failures. If i would have a way to at least semi-reliable reproduce the problem i would create a new bug and would debug and fix it. But i don't. And the changes i made is simply a way to let this test to run even on the problematic host because the problem that happens have nothing to do with the functionality related to the test itself.
I couldn't link this comment to the code because GitHub does not allow adding comments to unmodified lines. Do I understand correctly that you're for leaving it as is? |
Pretty much. Making frame volatile will not change the behavior, the assignment to it made in one place and it's on EDT inside invokeAndWait block, making it volatile will change nothing, it will be fully assigned by the time we leave EDT. And calling non-disruptive getters such getInsets or getBounds from main thread is not a problem either. By that time frame should be visible and in position - otherwise we will have much more interesting problems. |
|
@azuev-java This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 128 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
| BufferedImage fullScreen = robot.createScreenCapture(screen); | ||
| Graphics g = fullScreen.getGraphics(); | ||
| g.setColor(Color.RED); | ||
| g.drawRect(locx - 1, locy - 1, frw + 1, frh + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we need to call g.dispose to dispose this object which we normallydo after getGraphics() call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not necessary in such a short test, JVM will exit after test ends which will clear all the resources captured by this Graphics instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW it will be closed/released only if the tests are run in the othervm mode, but jtreg tests might share the single VM for a group of tests.
|
/integrate |
|
@azuev-java Since your change was applied there have been 175 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit 5eb2091. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |

Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/2790/head:pull/2790$ git checkout pull/2790