<AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

<AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
[JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.

It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.

It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.

I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

-------------

Commit messages:
 - 8263311: Watch registry changes for remote printers update instead of polling

Changes: https://git.openjdk.java.net/jdk/pull/2915/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=2915&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8263311
  Stats: 207 lines in 3 files changed: 31 ins; 158 del; 18 mod
  Patch: https://git.openjdk.java.net/jdk/pull/2915.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/2915/head:pull/2915

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
On Wed, 10 Mar 2021 15:38:27 GMT, Alexey Ivanov <[hidden email]> wrote:

> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>
> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>
> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>
> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp line 259:

> 257:                                                          NULL,
> 258:                                                          FALSE);
> 259:         if (keepMonitoring) {

I guess having "FALSE" as fAsynchronous  value mean the function does not return until a change has occurred so do we still need this do-while monitoring loop? And if the function fails once, should we stop monitoring?

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
On Thu, 11 Mar 2021 10:39:56 GMT, Prasanta Sadhukhan <[hidden email]> wrote:

> I guess having "FALSE" as fAsynchronous value mean the function does not return until a change has occurred so do we still need this do-while monitoring loop?

You're right, `FALSE` for `fAsynchronous` means the function doesn't return until a change occurred.

If a change occurs, we refresh the list of print services and then start to wait again. If we exit the loop, we'll not catch other changes that may occur.

> And if the function fails once, should we stop monitoring?
I followed Sergey's approach in `notifyLocalPrinterChange`, namely if `FindNextPrinterChangeNotification` returns an error, we quit the loop.

I can't see how we can fix the error if it occurs. Will it succeed the next time? Probably not. Thus I decided to quit the loop in case of an error.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
On Thu, 11 Mar 2021 10:54:12 GMT, Alexey Ivanov <[hidden email]> wrote:

>> src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp line 259:
>>
>>> 257:                                                          NULL,
>>> 258:                                                          FALSE);
>>> 259:         if (keepMonitoring) {
>>
>> I guess having "FALSE" as fAsynchronous  value mean the function does not return until a change has occurred so do we still need this do-while monitoring loop? And if the function fails once, should we stop monitoring?
>
>> I guess having "FALSE" as fAsynchronous value mean the function does not return until a change has occurred so do we still need this do-while monitoring loop?
>
> You're right, `FALSE` for `fAsynchronous` means the function doesn't return until a change occurred.
>
> If a change occurs, we refresh the list of print services and then start to wait again. If we exit the loop, we'll not catch other changes that may occur.
>
>> And if the function fails once, should we stop monitoring?
> I followed Sergey's approach in `notifyLocalPrinterChange`, namely if `FindNextPrinterChangeNotification` returns an error, we quit the loop.
>
> I can't see how we can fix the error if it occurs. Will it succeed the next time? Probably not. Thus I decided to quit the loop in case of an error.

I also am not sure on this. But I think since this is for remote printer, sometimes network availability issue might be there so it may fail more compared to local printer so I guess we should give this method a fair chance, more than that of local printer change, and not bail out on one failure.....maybe try out after some duration...or 5 times spaced out...as you did for the other EnumPrinter fix..

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
On Thu, 11 Mar 2021 11:30:52 GMT, Prasanta Sadhukhan <[hidden email]> wrote:

>>> I guess having "FALSE" as fAsynchronous value mean the function does not return until a change has occurred so do we still need this do-while monitoring loop?
>>
>> You're right, `FALSE` for `fAsynchronous` means the function doesn't return until a change occurred.
>>
>> If a change occurs, we refresh the list of print services and then start to wait again. If we exit the loop, we'll not catch other changes that may occur.
>>
>>> And if the function fails once, should we stop monitoring?
>> I followed Sergey's approach in `notifyLocalPrinterChange`, namely if `FindNextPrinterChangeNotification` returns an error, we quit the loop.
>>
>> I can't see how we can fix the error if it occurs. Will it succeed the next time? Probably not. Thus I decided to quit the loop in case of an error.
>
> I also am not sure on this. But I think since this is for remote printer, sometimes network availability issue might be there so it may fail more compared to local printer so I guess we should give this method a fair chance, more than that of local printer change, and not bail out on one failure.....maybe try out after some duration...or 5 times spaced out...as you did for the other EnumPrinter fix..

No, network connectivity cannot affect this. The function watches for registry changes, specifically keys created or removed under `HKCU\Printers\Connections`. If network is down, you won't be able to add a new printer. Yet you can still remove an existing printer.

The case with `EnumPrinters` is very different. A printer may be renamed or a new printer may be added therefore the allocated buffer becomes to small to fit the updated data. Thus retrying with larger buffer makes perfect sense.

In this case, `RegNotifyChangeKeyValue` could fail only because of invalid parameters. If it does, it will fail on the retry because the parameters haven't changed.

In that sense, it's the same as with local printers. If the wait/notification function fails the first time, it will likely fail the second time and so on…

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
In reply to this post by Alexey Ivanov-2
On Wed, 10 Mar 2021 15:38:27 GMT, Alexey Ivanov <[hidden email]> wrote:

> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>
> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>
> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>
> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp line 258:

> 256:                                                          REG_NOTIFY_CHANGE_NAME,
> 257:                                                          NULL,
> 258:                                                          FALSE);

[`RegNotifyChangeKeyValue`](https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regnotifychangekeyvalue) notifies the caller about changes to the attributes or contents of a specified registry key.

• `hKey`: A handle to `HKEY_CURRENT_USER\Printers\Connections` key which is opened above.
• `bWatchSubtree = TRUE`: The function reports changes in the specified key and its subkeys.
• `dwNotifyFilter = REG_NOTIFY_CHANGE_NAME`: Notify the caller if a subkey is added or deleted.
• `hEvent = NULL`: If `fAsynchronous` is FALSE, `hEvent` is ignored.
• `fAsynchronous = FALSE`: The function does not return until a change has occurred.

When a new remote printer is added, a new key is created under `HKCU\Printers\Connections`; when an existing remote printer is removed, the key below `Connections` is removed; no values are added or removed in `Connections` key, thus `REG_NOTIFY_CHANGE_LAST_SET` filter is not needed.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
In reply to this post by Alexey Ivanov-2
On Thu, 11 Mar 2021 14:49:59 GMT, Alexey Ivanov <[hidden email]> wrote:

>> I also am not sure on this. But I think since this is for remote printer, sometimes network availability issue might be there so it may fail more compared to local printer so I guess we should give this method a fair chance, more than that of local printer change, and not bail out on one failure.....maybe try out after some duration...or 5 times spaced out...as you did for the other EnumPrinter fix..
>
> No, network connectivity cannot affect this. The function watches for registry changes, specifically keys created or removed under `HKCU\Printers\Connections`. If network is down, you won't be able to add a new printer. Yet you can still remove an existing printer.
>
> The case with `EnumPrinters` is very different. A printer may be renamed or a new printer may be added therefore the allocated buffer becomes to small to fit the updated data. Thus retrying with larger buffer makes perfect sense.
>
> In this case, `RegNotifyChangeKeyValue` could fail only because of invalid parameters. If it does, it will fail on the retry because the parameters haven't changed.
>
> In that sense, it's the same as with local printers. If the wait/notification function fails the first time, it will likely fail the second time and so on…

Ok

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
In reply to this post by Alexey Ivanov-2
On Thu, 11 Mar 2021 14:59:55 GMT, Alexey Ivanov <[hidden email]> wrote:

>> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
>> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>>
>> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>>
>> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>>
>> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.
>
> src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp line 258:
>
>> 256:                                                          REG_NOTIFY_CHANGE_NAME,
>> 257:                                                          NULL,
>> 258:                                                          FALSE);
>
> [`RegNotifyChangeKeyValue`](https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regnotifychangekeyvalue) notifies the caller about changes to the attributes or contents of a specified registry key.
>
> • `hKey`: A handle to `HKEY_CURRENT_USER\Printers\Connections` key which is opened above.
> • `bWatchSubtree = TRUE`: The function reports changes in the specified key and its subkeys.
> • `dwNotifyFilter = REG_NOTIFY_CHANGE_NAME`: Notify the caller if a subkey is added or deleted.
> • `hEvent = NULL`: If `fAsynchronous` is FALSE, `hEvent` is ignored.
> • `fAsynchronous = FALSE`: The function does not return until a change has occurred.
>
> When a new remote printer is added, a new key is created under `HKCU\Printers\Connections`; when an existing remote printer is removed, the key below `Connections` is removed; no values are added or removed in `Connections` key, thus `REG_NOTIFY_CHANGE_LAST_SET` filter is not needed.

Is this only about addition/removal? What about printer name change? Shouldn't we get notified in that case as trying to print on printer with old name will not find the printer!!
If yes, in that regard I guess REG_NOTIFY_CHANGE_LAST_SET is the one to go for as it states
`"Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. "`

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
On Fri, 12 Mar 2021 04:55:45 GMT, Prasanta Sadhukhan <[hidden email]> wrote:

> Is this only about addition/removal? What about printer name change?

You cannot change the name of a remote printer.

Opening *Printer Properties* dialog from the printer context menu on the local host and editing its name changes the name of the printer on the remote host which shares it. Windows warns, “This is a shared printer. If you rename a shared printer, existing connections to this printer from other computers will break and will have to be created again.”

Nothing has been updated on the local system after renaming the printer. As the warning said, the printer does not work any more because it refers to a printer that does not exist.

To fix this, one has to add a new remote printer which refers to the new name of the printer on the remote host.

> Shouldn't we get notified in that case as trying to print on printer with old name will not find the printer!!

I'm afraid there's nothing Java can do to mitigate renaming the printer.

> If yes, in that regard I guess `REG_NOTIFY_CHANGE_LAST_SET` is the one to go for as it states
> _"Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. "_

Since no values are created, removed, or changed when a remote printer is added or removed under `Connections` key, adding `REG_NOTIFY_CHANGE_LAST_SET` to `dwNotifyFilter` is not required. There are some values stored in the printer key but Java does not use them directly; if any value is changed there, getting notifications about such an event only creates noise.

So, as far as Java is concerned, getting notifications about new keys being created or removed under `Connections` is enough. This is what `REG_NOTIFY_CHANGE_NAME` filter does.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
On Fri, 12 Mar 2021 11:29:17 GMT, Alexey Ivanov <[hidden email]> wrote:

>> Is this only about addition/removal? What about printer name change? Shouldn't we get notified in that case as trying to print on printer with old name will not find the printer!!
>> If yes, in that regard I guess REG_NOTIFY_CHANGE_LAST_SET is the one to go for as it states
>> `"Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. "`
>
>> Is this only about addition/removal? What about printer name change?
>
> You cannot change the name of a remote printer.
>
> Opening *Printer Properties* dialog from the printer context menu on the local host and editing its name changes the name of the printer on the remote host which shares it. Windows warns, “This is a shared printer. If you rename a shared printer, existing connections to this printer from other computers will break and will have to be created again.”
>
> Nothing has been updated on the local system after renaming the printer. As the warning said, the printer does not work any more because it refers to a printer that does not exist.
>
> To fix this, one has to add a new remote printer which refers to the new name of the printer on the remote host.
>
>> Shouldn't we get notified in that case as trying to print on printer with old name will not find the printer!!
>
> I'm afraid there's nothing Java can do to mitigate renaming the printer.
>
>> If yes, in that regard I guess `REG_NOTIFY_CHANGE_LAST_SET` is the one to go for as it states
>> _"Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. "_
>
> Since no values are created, removed, or changed when a remote printer is added or removed under `Connections` key, adding `REG_NOTIFY_CHANGE_LAST_SET` to `dwNotifyFilter` is not required. There are some values stored in the printer key but Java does not use them directly; if any value is changed there, getting notifications about such an event only creates noise.
>
> So, as far as Java is concerned, getting notifications about new keys being created or removed under `Connections` is enough. This is what `REG_NOTIFY_CHANGE_NAME` filter does.

I can understand that as a user, you cannot /shouldn't change the name of a remote network printer but a network admin can change the name, so shouldn't we get notification on that name change when this method gets called after the name change? or would it be notified as a new printer in that case? Then what will happen to the old stale printer in the registry?

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
On Fri, 12 Mar 2021 11:38:08 GMT, Prasanta Sadhukhan <[hidden email]> wrote:

>>> Is this only about addition/removal? What about printer name change?
>>
>> You cannot change the name of a remote printer.
>>
>> Opening *Printer Properties* dialog from the printer context menu on the local host and editing its name changes the name of the printer on the remote host which shares it. Windows warns, “This is a shared printer. If you rename a shared printer, existing connections to this printer from other computers will break and will have to be created again.”
>>
>> Nothing has been updated on the local system after renaming the printer. As the warning said, the printer does not work any more because it refers to a printer that does not exist.
>>
>> To fix this, one has to add a new remote printer which refers to the new name of the printer on the remote host.
>>
>>> Shouldn't we get notified in that case as trying to print on printer with old name will not find the printer!!
>>
>> I'm afraid there's nothing Java can do to mitigate renaming the printer.
>>
>>> If yes, in that regard I guess `REG_NOTIFY_CHANGE_LAST_SET` is the one to go for as it states
>>> _"Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. "_
>>
>> Since no values are created, removed, or changed when a remote printer is added or removed under `Connections` key, adding `REG_NOTIFY_CHANGE_LAST_SET` to `dwNotifyFilter` is not required. There are some values stored in the printer key but Java does not use them directly; if any value is changed there, getting notifications about such an event only creates noise.
>>
>> So, as far as Java is concerned, getting notifications about new keys being created or removed under `Connections` is enough. This is what `REG_NOTIFY_CHANGE_NAME` filter does.
>
> I can understand that as a user, you cannot /shouldn't change the name of a remote network printer but a network admin can change the name, so shouldn't we get notification on that name change when this method gets called after the name change? or would it be notified as a new printer in that case? Then what will happen to the old stale printer in the registry?

You can't. Try it yourself. The printer connection is per-user, after all it's stored under HKCU.

Windows displays the name of remote printers as “Generic / Text Only on 192.168.1.18”: _the name of the printer_ and _the remote host_.

If you open the *Printer Properties* dialog of a remote printer and edit its name, you change the name of the printer on the remote host which shares it. It changes *absolutely nothing* on the local system.

> shouldn't we get notification on that name change when this method gets called after the name change?

Yes, we should. But we cannot.

For Windows, nothing has changed on the local system, it's the remote system that has been changed.

> or would it be notified as a new printer in that case?

No, it wouldn't _because nothing has changed on the local system_.

> Then what will happen to the old stale printer in the registry?

Nothing, again. It just stays there but Windows reports an error if you try to open its Printer Properties, Windows reports an error if you try to print to it. I tried printing with Java and Notepad: the behaviour is the same. The difference is that Notepad displays the error message whereas Java throws an exception (it depends on the Java app, I guess).

The behaviour aligns to the one seen when the printer is unreachable because of, let's say, network issues.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
In reply to this post by Alexey Ivanov-2
On Wed, 10 Mar 2021 15:38:27 GMT, Alexey Ivanov <[hidden email]> wrote:

> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>
> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>
> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>
> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

Marked as reviewed by psadhukhan (Reviewer).

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Prasanta Sadhukhan-2
In reply to this post by Alexey Ivanov-2
On Fri, 12 Mar 2021 12:30:13 GMT, Alexey Ivanov <[hidden email]> wrote:

>> I can understand that as a user, you cannot /shouldn't change the name of a remote network printer but a network admin can change the name, so shouldn't we get notification on that name change when this method gets called after the name change? or would it be notified as a new printer in that case? Then what will happen to the old stale printer in the registry?
>
> You can't. Try it yourself. The printer connection is per-user, after all it's stored under HKCU.
>
> Windows displays the name of remote printers as “Generic / Text Only on 192.168.1.18”: _the name of the printer_ and _the remote host_.
>
> If you open the *Printer Properties* dialog of a remote printer and edit its name, you change the name of the printer on the remote host which shares it. It changes *absolutely nothing* on the local system.
>
>> shouldn't we get notification on that name change when this method gets called after the name change?
>
> Yes, we should. But we cannot.
>
> For Windows, nothing has changed on the local system, it's the remote system that has been changed.
>
>> or would it be notified as a new printer in that case?
>
> No, it wouldn't _because nothing has changed on the local system_.
>
>> Then what will happen to the old stale printer in the registry?
>
> Nothing, again. It just stays there but Windows reports an error if you try to open its Printer Properties, Windows reports an error if you try to print to it. I tried printing with Java and Notepad: the behaviour is the same. The difference is that Notepad displays the error message whereas Java throws an exception (it depends on the Java app, I guess).
>
> The behaviour aligns to the one seen when the printer is unreachable because of, let's say, network issues.

OK.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Sergey Bylokhov-2
In reply to this post by Alexey Ivanov-2
On Wed, 10 Mar 2021 15:38:27 GMT, Alexey Ivanov <[hidden email]> wrote:

> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>
> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>
> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>
> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

@aivanov-jdk can you please check what that old comment was about:

https://bugs.openjdk.java.net/browse/JDK-8153732?focusedCommentId=14188974&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14188974

Any idea why RegistryValueChange was rejected as a solution?

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
On Sat, 13 Mar 2021 00:18:25 GMT, Sergey Bylokhov <[hidden email]> wrote:

> Any idea why RegistryValueChange was rejected as a solution?

I've no idea. I read that comment, it's exactly the comment that was in the code above `RemotePrinterChangeListener` class in `PrintServiceLookupProvider.java`.

> RegistryValueChange cannot be used in combination with WMI to get registry value change notification because of an error that may be generated because the scope of the query would be too big to handle(at times).

It's very vague. I don't know what it really means. Neither do I know if a prototype was even tried.

If fact, this comment cites portions of the article [How to listen for Printer Connections?](https://docs.microsoft.com/en-gb/archive/blogs/hmahrt/how-to-listen-for-printer-connections). The link to this article is in the description of [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732).

The article discusses the subject with WMI and WQL. This is what it says:

> There is no equivalent to `FindFirstPrinterChangeNotification`, which listens for new/changed Printer Connections – and a polling mechanism was not an option. However, there is another way, using WMI.

Note: _polling mechanism was not an option_. Yet it is what was implemented in Java.

Then the articles describes the steps needed to monitor for printer changes.

Close to the end, there's the quoted sentence:

> Unfortunately, we cannot use the `RegistryValueChangeEvent` (because the scope of the query would be too big (we’d receive an error message), so we can only know **when** something changed below the `Printers\Connections` key, but not **what**. This is why we have to rely on **`EnumPrinters`**.

This statement is a bit confusing. It says they cannot use `RegistryValueChangeEvent` (it's not a Windows API function, it's another WMI class) but the WQL query above _uses it_.

I interpret the following statement this way: Registry notifications do not provide information on **what** changed under `Printers\Connections`, only that a change occurred. So `EnumPrinters` is used to enumerate the remote printers and update the stored list of printers after the change to the registry occurs.

I used this article as the inspiration and the implementation I'm proposing in this PR is purely based on this article. Yet I'm using Windows API function [RegNotifyChangeKeyValue](https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regnotifychangekeyvalue) to watch for registry updates and to get notified as soon as a change under `HKCU\Printers\Connections` occurs. Then the list of printers is updated by the `refreshServices` upcall into Java which refreshes both _local_ and _remote_ printers.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

Re: <AWT Dev> RFR: 8263311: Watch registry changes for remote printers update instead of polling

Sergey Bylokhov-2
In reply to this post by Alexey Ivanov-2
On Wed, 10 Mar 2021 15:38:27 GMT, Alexey Ivanov <[hidden email]> wrote:

> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>
> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>
> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>
> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

Marked as reviewed by serb (Reviewer).

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915
Reply | Threaded
Open this post in threaded view
|

<AWT Dev> Integrated: 8263311: Watch registry changes for remote printers update instead of polling

Alexey Ivanov-2
In reply to this post by Alexey Ivanov-2
On Wed, 10 Mar 2021 15:38:27 GMT, Alexey Ivanov <[hidden email]> wrote:

> [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732) implemented polling for remote printers.
> That bug description also mentions watching the registry for changes and links to the article which describes the method yet it does so in terms of WMI. Using WMI is not necessary to watch for the registry updates.
>
> It is possible to replace polling mechanism with registry change notifications. If the registry at `HKCU\Printers\Connections` is updated, refresh the list of print services.
>
> It works perfectly well in my own testing with sharing a Generic / Text Only printer from another laptop. The notification comes as soon as the printer is installed, it results in a new key created under `Connections`. If a remote printer is removed, the notification is also triggered as the key corresponding to that printer is removed from the registry.
>
> I updated the steps in the manual test: `RemotePrinterStatusRefresh.java`.

This pull request has now been integrated.

Changeset: a85dc557
Author:    Alexey Ivanov <[hidden email]>
URL:       https://git.openjdk.java.net/jdk/commit/a85dc557
Stats:     207 lines in 3 files changed: 31 ins; 158 del; 18 mod

8263311: Watch registry changes for remote printers update instead of polling

Reviewed-by: psadhukhan, serb

-------------

PR: https://git.openjdk.java.net/jdk/pull/2915