Может обнаруживать системные параметры прокси-сервера в приложении Java, но не в JUnit

  • Windows 7
  • Java 1.8.0_45
  • Eclipse Mars

Если у вас есть системный прокси, настроенный на HTTP, ниже будет печатать HTTP только в том случае, если он работает от метода main java-приложения.

Однако, если он вызывается из теста JUnit 4 (в eclipse), он всегда печатает DIRECT.

Также отмечается, что определение -Djava.net.useSystemProxies=true в eclipse: Запустить конфигурации → Аргументы → аргументы VM. Тест просто зависает.

Любая идея, что происходит?

Большое спасибо,

public void printSystemProxy() {
    System.setProperty("java.net.useSystemProxies", "true");
    try {
        final List<Proxy> list = ProxySelector.getDefault().select(new URI("http://foo/bar"));
        for (final Proxy proxy : list) {
            System.out.println(proxy.type());
        }
    } 
    catch (final URISyntaxException e) {
        throw new IllegalStateException(e);
    }
}

Ответы

Ответ 1

попробуйте создать конфигурацию TestRunner (щелкните правой кнопкой мыши /RunAs...) со следующими параметрами VM:

-Dhttp.proxyHost=<YOUR_PROXY>
-Dhttp.proxyPort=<YOUR_PORT>
-Dhttp.nonProxyHosts=<IF YOU NEED THIS (pipe as separator)>
-Dhttp.proxyUser=<YOUR_NAME>
-Dhttp.proxyPassword=<YOUR_PASWORD>

Ответ 2

Параметры прокси-сервера, установленные в Eclipse, будут влиять на все инструменты, включая Eclipse и Maven. Это может быть причиной того, что у вас "зависание"... возможно, это не был ваш тест JUnit, но сам maven висел (нужно уточнить).

Однако в этом случае мне кажется, что вы можете изменить Свойства системы из плагина, ответственного за тесты JUnit:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
      <systemPropertyVariables>
        <java.net.useSystemProxies>true</java.net.useSystemProxies>
      </systemPropertyVariables>
    </configuration>
  </plugin>

[ОБНОВЛЕНИЕ]

В некоторых случаях системное свойство используется только при запуске и работает только при его установке в командной строке. В этом случае вы можете предоставить его как часть аргументов командной строки:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
      <argLine>-Djava.net.useSystemProxies=true</argLine>
    </configuration>
  </plugin>

Также обратите внимание, что если вы хотите запустить его из maven, вам нужно выбрать "Run as → Maven test", а не "Run As → JUnit Test".

[ПОДРОБНЕЕ]

Ненавижу говорить об этом, но на данный момент поддержка Proxies на самом деле плохой в Java.

Достигнуто одно существенное улучшение: теперь вы можете определить отдельный прокси для каждого соединения, которое вы хотите установить. Однако я думаю, что это должно быть улучшено много:

  • Отдельная проверка подлинности на прокси-сервер. Теперь, хотя я могу определить прокси для каждого соединения, просто неестественно использовать одну и ту же аутентификацию для всех. Хуже того, он даже запускает ту же аутентификацию как для прокси, так и для HTTP-соединения: он не может отличить эти два четных.
  • Лучшая поддержка прокси SOCKS
  • Лучшая поддержка для запроса системы для настройки прокси. Каждая современная ОС теперь имеет конфигурацию для прокси-сервера по умолчанию.
  • Встроенная поддержка и API для реальных серверов Socket.

Похоже на тирады разочарованного программиста, но ответ заключается в их реализации! Является ли это достойным JEP?

Ответ 3

Вы не можете изменить поведение прокси-сервера Java во время выполнения. Системное свойство java.net.useSystemProxies считывается только при запуске. Из документации (выделено мной):

java.net.useSystemProxies(по умолчанию: false)

В последних системах Windows и в системах Gnome 2.x можно рассказать стек java.net, установив для этого свойства значение true, чтобы использовать параметры прокси-сервера системы (обе эти системы позволяют устанавливать прокси-серверы по всему миру через свой пользовательский интерфейс). Обратите внимание, что это свойство проверяется только один раз при запуске.

Установка системного свойства "на лету" не изменит поведение. Вы должны отправить его как аргумент JVM, используя -D, как вы делаете с вашим методом main. Альтернативой было бы не использовать системные прокси и вместо этого позволить пользователю предоставлять свои собственные.

В качестве альтернативы другие свойства прокси, такие как http.proxyHost, http.proxyPort и т.д. (перечисленные в ссылке на документацию выше), могут быть изменены после запуска приложения. В зависимости от вашего приложения это может быть лучшим решением в любом случае, поскольку оно обычно имеет лучшую кросс-платформенную поддержку.