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
6521141: DebugGraphics NPE @ setFont(); #9673
Conversation
👋 Welcome back tr! A progress list of the required criteria for merging this PR into |
|
@TejeshR13 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
|
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 guess exposing no-args public constructor was wrong and it should have been protected from beginning.
Also, please add a testcase.
" Setting clipRect: " + (new Rectangle(x, y, width, height)) + | ||
" New clipRect: " + graphics.getClip()); | ||
" Setting clipRect: " + (new Rectangle(x, y, width, height)) + | ||
" New clipRect: " + graphics.getClip()); |
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.
Why this line change is needed? Probably you have added some tabs..Remove this change and similarly from other logs down below.
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 think auto indentation has caused this, will undo these tabs changes.
Yeah, its been used internally by other constructors after setting the |
Even if it hadn't failed the test, you cannot simply change a method, constructor, or field in a public (or protected) class in an exported package from public to protected, since that would be an incompatible API change (at least not without a very compelling reason and a lot of discussion, and even then, probably not). |
Yeah, sure @kevinrushforth. |
You wrote " The graphics object is not initialized anywhere inside the class, where it is expected to set explicitly by the user. " which reads a bit like if the user does So any DebugGraphics created this way is useless. The javadoc for the class says : So likely no one should be doing this. I'd just add javadoc saying "This constructor should not be called by applications, it The only other thing I can think of is to try to figure out by using if it was called from outside DebugGraphics, and if so install some other graphics instead. something like .. |
Yeah, this looks like a better idea @prrace. I will update the java doc and also will create the BufferedImage graphics from the no-arg constructor. With this we will be warning about the usage of no-arg constructor to user and also handle NPE cases. |
// Creates a Graphics context when Application calls the constructor | ||
// directly. | ||
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); | ||
if ((graphics == null) && (walker.getCallerClass() != this.getClass())) { |
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 know if creating a StackWalker is expensive but I think it should be done only if graphics == null
Also the version of getInstance() being called here might throw SecurityException
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/StackWalker.html#getInstance(java.lang.StackWalker.Option)
So you'll need to wrap it in a doPrivileged.
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.
Checking only if graphics == null
will also handle the case when user sets the graphics
to null by passing null in the constructor, so removing StackWalker and checking only for graphics == null
will handle both the cases whether its internal class or called from other class.
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.
@prrace Then I will proceed by removing Stackwalker and create a graphics instance only if its null
.
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.
No, because that won't work, or more precisely will be a waste of work.
See
DebugGraphics(Graphics graphics) {
this(); // << no-args constructor and graphics will still be null
this.graphics = null;
}
graphics will ALWAYS be null when you come via here which is exactly why we needed StackWalker
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, then we should set graphics only If the no-args constructor is called by another program and not via by the same class. I had understood the previous suggestion wrongly, now I got it. We are supposed to create instance of stackwalker only if graphics is null and wrap it around doPrivileged.
…tions based on review
} | ||
}); | ||
|
||
if(walker.getCallerClass() != this.getClass()) { |
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.
Let's add space after if
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.
Updated.
@@ -72,11 +74,32 @@ public class DebugGraphics extends Graphics { | |||
/** | |||
* Constructs a new debug graphics context that supports slowed | |||
* down drawing. | |||
* <p> | |||
* NOTE: This constructor should not be called by | |||
* application, it is for Internal use only. When called directly |
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.
"application" -> "applications"
"Internal" -> "internal"
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.
Updated.
|
||
/* @test | ||
* @bug 6521141 | ||
* @key headful |
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.
Why does this test need to be headful ?
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.
Actually not required, since no UI is used..... Will remove and test......
@prrace, I have updated the PR, let me know if its ok now...... |
*/ | ||
public class DebugGraphicsNPETest { | ||
public static void main(String[] args) throws Exception { | ||
SwingUtilities.invokeAndWait(new Runnable() { |
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.
No need of using EDT here as no Swing components in used. You can just move runTest() lines in main..
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.
Yeah right. I have updated the test @prsadhuk
public DebugGraphics() { | ||
super(); | ||
buffer = null; | ||
xOffset = yOffset = 0; | ||
|
||
// Creates a Graphics context when the constructor is called. | ||
if (graphics == null) { |
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.
Probably it will be better to use this.graphics
here and below while setting.
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.
Updated @prsadhuk .
@TejeshR13 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 329 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. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@prsadhuk, @prrace) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
/integrate |
@TejeshR13 |
/sponsor |
Going to push as commit 21f4eb2.
Your commit was automatically rebased without conflicts. |
@prsadhuk @TejeshR13 Pushed as commit 21f4eb2. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
DebugGraphics
class has a Graphics instance which is been used in slowed down drawing. Thegraphics
object is not initialized anywhere inside the class, where it is expected to set explicitly by the user. When the user doesn't set it and try to use the any mehtods likedrawing/setFont
, NPE is raised which is expected. The scenario is taken care by checking if thegraphics
object is null before using it inside the class, thus eliminating the NPE case.Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/9673/head:pull/9673
$ git checkout pull/9673
Update a local copy of the PR:
$ git checkout pull/9673
$ git pull https://git.openjdk.org/jdk pull/9673/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 9673
View PR using the GUI difftool:
$ git pr show -t 9673
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/9673.diff