Реальная проблема заключается в том, что Java предполагает, что проверка «Использовать один и тот же прокси-сервер для всех протоколов» также влияет на прокси-сервер SOCKS (я не знаю логику этого диалога в Windows, но это, по крайней мере, сбивает с толку)
Если проверка установлена, вы получаете включенные прокси как для HTTP, так и для SOCKS, что вряд ли будет желаемой конфигурацией.
Один из способов решить эту проблему - снять отметку с чека и оставить поле SOCKS незаполненным.
Я наконец решил, создав ProxySelector, который сначала вызывает селектор по умолчанию, и если он находит ту же конфигурацию для соединений HTTP и SOCKS, он пропускает прокси SOCKS.
public class SocksFixerProxySelector extends ProxySelector {
ProxySelector base;
public SocksFixerProxySelector() {
base = ProxySelector.getDefault();
}
@Override
public List<Proxy> select(URI uri) {
List<Proxy> baseList = base.select(uri);
try {
if (uri.getScheme().equals("socket")) {
Proxy socksProxy = findByType(baseList, Type.SOCKS);
if (socksProxy != null) {
URI httpTestUri = new URI("http", uri.getHost(), uri.getPath(), uri.getFragment());
Proxy httpProxy = findByType(base.select(httpTestUri), Type.HTTP);
if (httpProxy != null && socksProxy.address().equals(httpProxy.address())) {
// Quitamos SOCKS
List<Proxy> filteredList = new ArrayList<>(baseList);
filteredList.remove(socksProxy);
return filteredList;
}
}
}
} catch (Exception e) {
}
return baseList;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
base.connectFailed(uri, sa, ioe);
}
private Proxy findByType(List<Proxy> proxies, Proxy.Type type) {
for (Proxy proxy : proxies) {
if (proxy.type() == type)
return proxy;
}
return null;
}
Возможно, лучшим решением было бы проверить реестр и определить правильные настройки, но я не хотел связываться с конкретным кодом Windows (и все эти настройки скриптов тоже выглядели плохо)