Can detect system Proxy Settings in Java application, but not in JUnit
Asked Answered
K

3

15
  • Windows 7
  • Java 1.8.0_45
  • Eclipse Mars

If you have system proxy set up to HTTP, the below will print HTTP only if it runs from main method of java application.

However, if it is called from JUnit 4 test (in eclipse), it always prints DIRECT.

It is also noted that defining -Djava.net.useSystemProxies=true in eclipse: Run configurations -> Arguments -> VM arguments. The test simply hangs.

Any idea what is going on?

Thanks a lot,

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);
    }
}
Kephart answered 29/6, 2015 at 12:24 Comment(6)
Print out the content of System.getEnv() and System.getProperties() to the standard out in case of main method and in case of JUnit and compare them. There will be surely some difference, which causes this problem.Charlatanism
How do you set up the proxy?Hearty
windows.microsoft.com/en-us/windows/…Kephart
What do you mean with "the test hangs after printing HTTP"? Does mvn -X provide some more information? What tests do you run in your MyTestClass.Florina
There is a single test method, which calls printSystemProxy. I tried again in a clean project, and maven returns, but still eclipse hangs with Junit if system property is defined.Kephart
Hanging eclipse: it doesn't even reach the BlockJUnit4ClassRunner constructor (as seen by debugging)Kephart
D
6

try making a TestRunner configuration (right-click/RunAs...) with the following VM parameters:

-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>
Docilla answered 6/7, 2015 at 12:53 Comment(1)
Thanks, but the ideas is not to specify any values, it should be part of test suite, where every machine detects the configuration from the system, whether in maven or eclipseKephart
C
3

You can't change Java's system proxy behavior on runtime. The java.net.useSystemProxies system property is only read on start-up. From the documentation (emphasis added):

java.net.useSystemProxies (default: false)

On recent Windows systems and on Gnome 2.x systems it is possible to tell the java.net stack, setting this property to true, to use the system proxy settings (both these systems let you set proxies globally through their user interface). Note that this property is checked only once at startup.

Setting the system property on the fly won't change the behavior. You have to send it in as a JVM argument using -D like you're doing with your main method. An alternative would be to not use the system proxies and instead allow the user to supply their own.

Alternatively, the other proxy properties like http.proxyHost, http.proxyPort, etc. (listed on the documentation link above) can be modified after the application has been started. Depending on your application, this may be a better solution anyway since it will generally have better cross-platform support.

Cotto answered 8/7, 2015 at 21:36 Comment(0)
A
3

The proxy settings you set within Eclipse will affect all tools including Eclipse and Maven itself. This might be the reason why you had a 'hang' ... it might not have been your JUnit test, but maven itself hanging (need clarification).

However, in this case, it appears to me that you can change the System Properties from within the plugin responsible for JUnit tests:

  <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>

[UPDATE]

In some cases the System Property is only used at startup, and only works when you set it at the command-line. In that case, you can supply it as part of the command-line arguments:

  <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>

Also note that if you want to run it from within maven, you have to choose 'Run as -> Maven test', and not 'Run As -> JUnit Test'.

[RANTING Follows]

I hate to say this - but at this point the support for Proxies is really poor within Java.

One major improvement has ever been made: now you can define a separate Proxy for each connection you want to establish. However, I think this should be improved by a lot:

  1. Separate authentication per proxy. Now even though I can define proxy per connection, it is just unnatural to use the same authentication for all. Worse, it even triggers the same authentication for both proxy and HTTP connection: it is not able to distinguish these two even.
  2. Better support for SOCKS proxies
  3. Better support to query the system for proxy setup. Every modern OS now has a configuration for default proxy.
  4. Built-in support and API's for actual Socket Servers.

Sounds like the rants of a disillusioned programmer, but the answer is in the implementation of these! Is this worthy a JEP?

Adulate answered 8/7, 2015 at 23:35 Comment(1)
The main purpose is to run with Eclipse, maven configuration was added since it was hanging, but then it became fine (possibly proxy issue). +1 for run as -> maven test, although that feature is at pom level, not on individual test case (as JUnit)Kephart

© 2022 - 2024 — McMap. All rights reserved.