Sitelet https://web.archive.org/web/20201023082853/https://github.com/dnsjava/dnsjava/issues/8
Skip to content
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

dnsjava and Java 9 #8

Closed
Stefan1200-de opened this issue Oct 7, 2017 · 29 comments
Closed

dnsjava and Java 9 #8

Stefan1200-de opened this issue Oct 7, 2017 · 29 comments
Assignees

Comments

@Stefan1200-de
Copy link

@Stefan1200-de Stefan1200-de commented Oct 7, 2017 •

While using dnsjava 2.1.8 with Java 9 on my Windows 10 system I get the following warning:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.xbill.DNS.ResolverConfig to method sun.net.dns.ResolverConfiguration.open()
WARNING: Please consider reporting this to the maintainers of org.xbill.DNS.ResolverConfig
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Are there plans to change this?

@ibauersachs ibauersachs closed this Oct 7, 2017
@ibauersachs ibauersachs reopened this May 18, 2019
@kentros
Copy link
Contributor

@kentros kentros commented May 19, 2019

I welcome suggestions. Here's my stab at a few solutions:

  1. Remove it altogether. With sun.* internal classes there is always a known fear things won't be there in the future. If we remove it, there are fallbacks in place. See the javadoc:
    * <LI>The sun.net.dns.ResolverConfiguration class is queried.
  2. Keep the current logic but add a block that detects if running on Java 9+, and if so skip it.
  3. Replace it with a different mechanism. Perhaps for Windows, we attempt a registry lookup on SearchList / NameServer ?
  4. Ignore it. It technically should be work until removed/changed. However, that WARNING message is hard to ignore. I'd hate to have to see that in my logs all the time as a consumer.

Any other thoughts? FWIW, here's what netty did: netty/netty#8319

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented May 19, 2019

Not sure if removing it without a better replacement is a good idea, the current code Windows is AFAIK locale-dependent.

If we use JDK9+ to compile the code, we can take advantage of the multi-release JARs and continue to use the existing class for Java 8. But different behavior depending on the runtime also is really uncool.

Querying the registry on Windows is a no go. This is what Java is currently doing, and it fails miserably: As soon as you have more than one NIC (i.e. almost every laptop), you have multiple DNS server addresses in the registry. Some of them might be from a WiFi connection that is now offline. Java still queries them... 🤦‍♂️
Using a proper networking API might be an alternative, but it would still require pulling in JNA.

@Dmole
Copy link

@Dmole Dmole commented May 19, 2019

If the feature is non-trivial

  1. Replace it with a different mechanism

break a minimal code set from sun.net.dns out into a library that can be independently maintained.

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented May 19, 2019

@Dmole sun.net.dns.ResolverConfigurationImpl uses native code from the net JVM library. Nameservers can already be manually set.

@bwelling
Copy link
Collaborator

@bwelling bwelling commented May 19, 2019

As a historical note, the reason for using the sun APIs is that none of the other methods (and there are a lot of them) worked all that well. The sun API worked reliably and consistently.

I expect that there still isn’t a good replacement, so all of the other methods may need to be improved.

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented May 19, 2019

Well, even the JVM class has its issues. I think we could go somewhere along the lines of parsing resolv.conf (that's what the JVM does anyway) and doing Windows API call with an optional dependency to JNA. If that's not available, fall back to something we have now.

@kingle
Copy link
Collaborator

@kingle kingle commented May 27, 2019

Could we add an SPI into the mix as the replacement? With this, it would allow consumers the ability to supply a provider to find the local nameserver and searchpath as appropriate. In order to at least mitigate the message, I'd also propose we change the order of the sun.net.dns.ResolverConfiguration so it's down below the /etc/resolv.conf finder so this issue doesn't occur when running in a Unix environment.

Proposed New Order:

  1. The properties dns.server and dns.search (comma delimited lists) are checked. The servers can either be IP addresses or hostnames (which are resolved using Java's built in DNS support).
  2. The service provider config file under META-INF/services is used to attempt all extentions, if they exist
  3. On Unix, /etc/resolv.conf is parsed.
  4. The sun.net.dns.ResolverConfiguration class is queried.
  5. On Windows, ipconfig/winipcfg is called and its output parsed. This may fail for non-English versions on Windows.
  6. As a last resort, localhost is used as the nameserver, and the search path is empty

Thoughts?

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented May 27, 2019

Sure, as long as the servers and providers are also configurable via direct API calls. I'm not a big fan of the automated static initialization that is done now, but haven't thought of how to replace it properly.

  1. The properties dns.server and dns.search (comma delimited lists) are checked. The servers can either be IP addresses or hostnames (which are resolved using Java's built in DNS support).

Resolving DNS servers by name doesn't make sense to me. And it could lead to a chicken-egg problem if someone is still using the SPI as a drop-in for Java's own (on Java 8 of course).

@kingle kingle self-assigned this May 28, 2019
@jpschewe jpschewe mentioned this issue May 29, 2019
7 of 7 tasks complete
@kingle
Copy link
Collaborator

@kingle kingle commented Jun 2, 2019

Proposed SPI interface:

public interface ResolverConfigProvider {
  /** Returns all located servers, or null if none could be located. */
  public String[] getServers() {
  /** Returns all entries in the located search path or null if none could be located. */
  public Name[] getSearchPath()

Questions: What package do we want this under? org.xbill.DNS.spi? Do we want to keep the existing return type as arrays or do we want a particular Collection instead? Do we want to short-circuit to done on the first implementation that can provide a name server or do we want to continue down the list for search suffixes if none are found?

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jun 3, 2019

I'd rater return List<> than an array (Set<> isn't really appropriate since the server are ordered). The existing spi package isn't the best option, it would make the exclusion of the NSP SPI more complicated and create a mix of functionalities. How about .config?

In addition to the interface methods above, each provider should probably have a method to indicate if it is enabled (or some other means to only run on certain OS). Some preference ordering mechanism should also be included, e.g. via a getPriority method.
Not sure when to abort. Could either be defined with an additional property on each provider, on the ResolverConfig or we simply stop once at least one address was found. The last one is closest to the existing behavior.

@kingle
Copy link
Collaborator

@kingle kingle commented Jun 3, 2019

👍 List<> return type instead of arrays.
👍org.xbill.DNS.config package
👍default boolean isEnabled() { return true; } method addition (implementations can use this to allow skipping them if they see any prerequisite is missing (not just OS, but maybe Java version, vendor, file missing, etc.)
👎 getPriority method. I'm not a fan of having implementations decide their own priority. For one, each implementation has no visibility of any of the other implementations -- nor should they -- so they can't make a very informed judgement on how they should be relatively sorted. In practice, I'd imagine they all would just default to setting "high" priority, which isn't helpful. In addition, one of the advantages to the service loader concept is that we can lazily load these until we find one that works. If we expose a priority, it means we'll have to load every implementation upfront and then sort them to run in a particular order.
❓ When to abort? I prefer matching existing behavior whenever possible, especially for the first round. Instead of a method on each provider implementation, we could document a distinction between implementations returning an empty List (e.g. confident there are no search suffixes configured) vs null (could not be determined). If we get an explicit null from an implementation, we keep going until we get non-null values. The first valued or empty List will allow for us to short-circuit to skip the rest. Alternatively, we could check for OperationNotSupportedException instead of null checks. Thoughts?

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jun 3, 2019

  • getPriority: Yes, handing out prios from a provider is not very nice. But without that, how do you want to order the reflection based SPI lower than the /etc/resolv.conf SPI on Unixes? There needs to be something that can indicate "don't use me, I'm just a last resort".
    Also, currently localhost is the lowest priority if nothing else can be found. But on systems with systemd-resolved, localhost should actually be the highest priority (since it takes care of per-NIC DNS server configurations, suffixes and also (optionally) performs DNSSEC validation).
  • Abort: Don't use null, use Optional<>. That seems a little weird for a method returning a List, but it makes the appropriate distinction between nothing and confidently empty. But most certainly not exceptions, exceptions are exceptional, not something that is expected to occur. I don't think we should distinguish between servers and suffixes though. A provider should be able to safely return both.
@kingle
Copy link
Collaborator

@kingle kingle commented Jun 3, 2019

On priority, my thought was we'd continue having a default, and the only real difference would be user-defined implementations get second-highest priority. The dns.server and dns.search system properties are still able to override anything. If those don't work, the next priority is to go through any user-specified provided implementations. If those don't work, then we use the existing logic to do resolv.conf on Unix, ipconfig on Windows, etc. If those don't work, try sun.net.dns.ResolverConfiguration class, localhost last.

Also, currently localhost is the lowest priority if nothing else can be found. But on systems with systemd-resolved, localhost should actually be the highest priority

If the default flow outlined is insufficient, I think we should expose priority as runtime options. How about we create a configuration (system property? env-var?) to allow overriding the ordering? That way, we can handle special cases.

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jun 4, 2019

How do you distinguish between internal/default SPIs and custom SPIs? Their package name?

+1 for making the priority configurable. We can then provide a hopefully sensible default ordering. This default order needs to be accessible somehow.
Java's security providers work similar. The default is configured in a property file, applications can iterate and modify this list (Security.getProviders() and Security.addProvider(...)).

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jun 4, 2019

Oh, and: dns.server and dns.search should be just an SPI like the others. Probably with default order 0, i.e. highest. But it should be possible to move it to a lower prio, e.g. to attempt detecting a system default and then fallback to a well-known public server (e.g. Google).

@kingle
Copy link
Collaborator

@kingle kingle commented Jun 4, 2019

How do you distinguish between internal/default SPIs and custom SPIs?

I was thinking that we keep our internal ones outside the SPI loading logic. We can still split them out into separate classes (or not) -- we don't need the ServiceLoader to load them since we have direct access.

Consumers could supply a list of what the desired ordering should be. We may want to come up with an enum that breaks these down into categories (e.g. SYS_PROPS, EXTERNAL, INTERNAL, LOCALHOST and maybe SUN). EXTERNAL would be for the SPI loading. Everything else we can invoke directly in whatever way we want.

@kingle
Copy link
Collaborator

@kingle kingle commented Jun 4, 2019

Any objection to splitting this issue down into a few more manageable issues? To circle back to the original problem, we mainly want to deal with warning messages Java 9+.

For that, I think we focus this issue on just the change to introduce a different default ordering and allow an override setting so users can dictate which one gets priority. At the very least, this allows non-Windows cases to avoid the message.

I'd like to move the SPI discussion into a separate issue, since that may end up being more of an overhaul and isn't directly related to the Java 9 warning message for most users.

Additionally, there is perhaps a glimmer of hope to alternatively see what OpenJDK may ultimately do. There's this issue: https://bugs.openjdk.java.net/browse/JDK-8211216 and this discussion thread: http://mail.openjdk.java.net/pipermail/net-dev/2018-September/011789.html

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jun 5, 2019

The immediate issue with the reflection warning might be best addressed with JNDI, just like Netty does it.

@kingle
Copy link
Collaborator

@kingle kingle commented Jun 5, 2019

+1 to use the JNDI approach

@simonmittag
Copy link

@simonmittag simonmittag commented Jan 2, 2020

Since this issue is now closed, when can we expect a 2.2.0 release? I'm using the dnsjava 2.1.9 on JDK13 and the issue persists.

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jan 7, 2020

The next release will be 3.0.0 and I don't have an ETA yet. It would help if you could test the current master branch and provide feedback.

@simonmittag
Copy link

@simonmittag simonmittag commented Jan 8, 2020

happy to help. Should we just build off master ourselves or is there a readily available pre-release build you want feedback on?

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jan 9, 2020

There are no -snapshot binaries, so yes, please just build from master.

(The reason I haven't published -snapshots at Sonatype is because it's complicated to get a CI only account and I don't want to put my own password into the this repo).

@lpellegr
Copy link

@lpellegr lpellegr commented Jan 14, 2020

It took me some time to find this issue and after giving a try with a build from the current master (6fc49f3), I noticed the original issue is still present when a lookup is made for instance using Java 13.

Any plan to really fix this issue that at least pollutes logs and might break apps in the future?

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jan 14, 2020

Thanks for testing and yes, I definitely want this fixed. Could you please provide a little more detail? I'm not seeing any errors on Java 11 anymore since #82 was merged.

@lpellegr
Copy link

@lpellegr lpellegr commented Jan 14, 2020

@ibauersachs Sure, you will find a code snippet with all information to reproduce on the next page:

https://gist.github.com/lpellegr/c1948b7a96b3487271a610ff7241dca7

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jan 14, 2020

The SunJvmProvider should only be used as a last resort. Can you please set the log level to debug?

And what OS is that running on? If Mac, since I don't have one, where/how should DNS server and the domain name be coming from? Is there a /etc/resolv.conf?

@ibauersachs ibauersachs assigned ibauersachs and unassigned kingle Jan 14, 2020
@lpellegr
Copy link

@lpellegr lpellegr commented Jan 15, 2020

@ibauersachs Running Fedora 31.

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Jan 18, 2020

@lpellegr The JVM config provider is now disabled by default. I assume it was still used in your setup because your resolv.conf didn't have a search path, so ResolverConfig continued to try to find a search path. This is moot since the JVM won't find a search path either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants
You can’t perform that action at this time.