Why Java net. Sockssocketimpl is the default Java net. Socket implementation?

The question is simple Why does a socks aware socket implementation implement Abstract Java net. The default choice of socket class? Naive, I would expect Java net. PlainSocketImpl.

The background is a little complicated

I tried to kill glassfish-12213 (or I really want to solve it) The details of the error itself are not important - there is a native library that is not thread safe, and some concurrent usage from the LDAP realm authored by GlassFish crashes the JVM

To solve this problem, I started working in reverse: can I avoid calling the native library first? This leads me to see sun for various reasons net. spi. Defaultproxyselector, responsible for finding an appropriate proxy (or not) for a given URI There is a spot in there that makes local method calls, which is where the JVM crash occurs If I can avoid this call, I will be in business

One way I can avoid this call is if I can ensure sun net. spi. NetProperties. The value of getboolean ("Java. Net. Usesystemproxies") is false If so, the native method I mentioned earlier will not be called False is the default. I haven't modified anything in this regard at all

(actually, this is the case; it can be proved in the GlassFish instance running on the wrong machine. I don't know how this code may still be loading the native library, which is the subject of another day.)

So, on this path, I make a further backup: in defaultproxyselector What protocol is passed as a URI scheme in a select (URI) call? Maybe I can influence stupid things in some way and still skip local calls in some way

It turns out that the protocol is socket (I think it may be like LDAP, but not) This fact and my reluctant assumption tell me that a direct socket is manually opened somewhere in LDAP real land (i.e. not using something like httpurlconnection or other abstractions) Sure enough, the ldap-jndi bridge written by sun did just that; The URI passed in is socket: / / somehost: 389

So from all this, despite the fact that I didn't set any agent information, configure anything or do anything, instead of using the direct default value, it turns out that JDK tried to use socks agent See the setimpl() method in Java net. Socket and line 364 or so of sockssocketimpl Java, learn more

(this finally shows that I can skip the entire CodePath. Jeez by simply adding a socksnonproxyhosts = * system attribute to the mix. Shouldn't this behavior be the default?)

Therefore, for some reason, the defaultproxyselector has hassystemproxies field set to true for some reason. Although there is no change in my or GlassFish configuration, the garden type socket created by the garden type sun LDAP connection causes the machine to find a socks proxy server Maybe it's just me, but that's what I'm crazy about

So people who have read this may - maybe you're on the JDK team, or know someone, or know the history here - know why Java net. The default implementation of socket always looks for a socks proxy?

Update: I can see the answer is: so if you have a system agent set up somewhere and enable socks, everything will flow through it But if Java net. The default value of usesystemproxies is false, so what does hunting (by default) mean for socks agents?

Solution

The default socket implementation is sockssocketimpl because the JRE may have passed the system properties - dsocksproxyhost and - dsocksproxyport or proxyselector Setdefault() or the default proxyselect installed through JRE is externally configured to use socks

Plainsocketimpl does not refer to these properties or classes (because it is an ordinary socket and should not know any agents), so these external configurations will be ignored. Sockssocketimpl is always called to check them I agree that it seems strange for you to receive a sockssocketimpl when no one Posts anything about socks to JRE, but I guess Java net. The architecture of socket and proxyselector does not allow the correct content to be selected in advance when the socket is instantiated

I think you (or who led the investigation of the current GlassFish Bug) may be in the wrong way: instead of trying to subvert the way JRE selects socket impls and proxy, why not fix the default proxyselector and / or OS native calls so that things will not be interrupted when Java makes standard queries on proxy information I think the fix is in the agent lookup process and class courage, not higher

Perhaps another way to ask me is: if defaultproxyselector can tell me that the proxy is used for socket connection, why does socket call it first to help it choose a reasonable implementation?

I think the problem is Java net. Socket supports a variety of programming models There is an obvious new socket (host, port) constructor, but there is also a default constructor socket () that can be constructed first, and then its connection (socketaddress) method can be called at any time in the future

Because proxyselector can be used to determine whether the agent should be used, some criteria are the names of the remote host and remote port to be connected (that is, the information provided for connect), that is, Java net. The socket constructor is too early to know if a proxy is required

Whatever the reason (we can assume history? / backward compatibility reason?:), Java net. The constructor of socket is the only meaning, that is, in some cases, it is too early in some cases, and a proxy will be required

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>